SlideShare a Scribd company logo
Mining Functional Patterns
Debasish Ghosh
@debasishg
Plan today ..
• Design Pattern

• Algebra

• Algebra <=> Functional Patterns

• Mining patterns on real world Scala code
Code ahead .. Scala code ..
.. though the principles apply
equally well to any statically typed
functional programming language ..
Solution to a Problem in Context
Design Pattern
Solution to a Problem in Context
Design Pattern
Solution to a Problem in Context
Design Pattern
Solution to a Problem in Context
Design Pattern
Solution to a Problem in Context
Design Pattern
we are given a problemgeneric component
(invariant across
context of application)
context dependent
(varies with the
context of problem)
What is an Algebra ?
Algebra is the study of algebraic structures
In mathematics, and more specifically in abstract algebra,
an algebraic structure is a set (called carrier
set or underlying set) with one or more finitary
operations defined on it that satisfies a list of axioms
- Wikipedia
(https://en.wikipedia.org/wiki/Algebraic_structure)
Set A
ϕ : A × A → A
for (a, b) ∈ A
ϕ(a, b)
a ϕ b
given
a binary operation
for specific a, b
or
The Algebra of Sets
3 + 2 = 5
7 + 4 = 11
2 + 0 = 2
0 + 6 = 6
8 + 9 = 9 + 8.
Binary operation
Identity operation
Associative operation
always produces an integer
(closure of operations)
One specific instance of the Algebra
Set A
ϕ : A × A → A
given
a binary operation
(a ϕ b) ϕ c = a ϕ (b ϕ c)
associative
for (a, b, c) ∈ A
Let’s enhance the Algebra ..
Set A
ϕ : A × A → A
given
a binary operation
(a ϕ b) ϕ c = a ϕ (b ϕ c)
associative
for (a, b, c) ∈ A
The Algebra of Semigroups
Set A
ϕ : A × A → A
given
a binary operation
(a ϕ b) ϕ c = a ϕ (b ϕ c)
associative
for (a, b, c) ∈ A
a ϕ I = I ϕ a = a
for (a, I ) ∈ A
identity
The Algebra of Monoids
Algebra <=> Protocol
class Monoid a where
mempty :: a
mappend :: a -> a -> a
Algebra <=> Protocol with Laws
class Monoid a where
mempty :: a
mappend :: a -> a -> a
-- Identity laws
x <> mempty = x
mempty <> x = x
-- Associativity
(x <> y) <> z = x <> (y <> z)
Monoid In Scala
trait Semigroup[A] {
def combine(x: A, y: A): A
}
trait Monoid[A] extends Semigroup[A] {
def empty: A
}
Monoid In Scala
trait Semigroup[A] {
def combine(x: A, y: A): A
}
trait Monoid[A] extends Semigroup[A] {
def empty: A
}
val intAdditionMonoid: Monoid[Int] = new Monoid[Int] {
def empty: Int = 0
def combine(x: Int, y: Int): Int = x + y
}
• algebra (interface)
• reusable
• polymorphic
• standard library code
• instance (implementation)
• specific for a datatype
val moneyAdditionMonoid: Monoid[Money] = new Monoid[Money] {
def empty: Money = ???
def combine(x: Money, y: Money): Money = ???
}
• domain specific instance
• specific for Money
• application library code
Monoid In Scala
trait Semigroup[A] {
def combine(x: A, y: A): A
}
trait Monoid[A] extends Semigroup[A] {
def empty: A
}
val intAdditionMonoid: Monoid[Int] = new Monoid[Int] {
def empty: Int = 0
def combine(x: Int, y: Int): Int = x + y
}
• algebra (interface)
• reusable
• polymorphic
• standard library code
• instance (implementation)
• specific for a datatype
val moneyAdditionMonoid: Monoid[Money] = new Monoid[Money] {
def empty: Money = ???
def combine(x: Money, y: Money): Money = ???
}
• domain specific instance
• specific for Money
• application library code
Generic
Specific
• Specific implementations
use the generic protocol/interface
• This reusability is enforced by
parametricity (no type specific info
in the protocol)
• Genericity implies reusability
Monoid In Scala
trait Semigroup[A] {
def combine(x: A, y: A): A
}
trait Monoid[A] extends Semigroup[A] {
def empty: A
}
val intAdditionMonoid: Monoid[Int] = new Monoid[Int] {
def empty: Int = 0
def combine(x: Int, y: Int): Int = x + y
}
• algebra (interface)
• reusable
• polymorphic
• standard library code
• instance (implementation)
• specific for a datatype
val moneyAdditionMonoid: Monoid[Money] = new Monoid[Money] {
def empty: Money = ???
def combine(x: Money, y: Money): Money = ???
}
• domain specific instance
• specific for Money
• application library code
Pattern
Instances
generic & reusable
context specific
Functional Patterns
• Generic, reusable algebra
• Parametric on types
• Clear separation between pattern (algebra) and
its instances
• Composable through function composition
Functional Patterns
• Standard vocabulary - people know these terms,
know these operations and their types
• Rich ecosystem support through standard
libraries
• Functions defined in only terms of these
interfaces / algebra can be reused by application
level data types that follow the pattern
Functional Patterns - freebies
• Given a type that has an instance of a Monoid, if we have a
List of such objects, we can combine them for free using
the combine function of Monoid.Also note that the
behavior of combine is completely polymorphic - depends
on the instance of Monoid that you pass in.
• Given a typeV that has an instance of a Monoid, Map[K,
V] also gets a Monoid. Part of standard library, but as an
application developer you get this for free.
• .. and there are many such examples ..
Functional Patterns - Multiplicative Power
Money: Monoid
Payment: Monoid
Foo: Monoid
Bar: Monoid
Polymorphic behaviors in the
library that expects a Monoid
Domain Model Types
with Monoid instances
def fold[A](fa: F[A])
(implicit A: Monoid[A]): A = // ..
def foldMap[A, B](fa: F[A])(f: A => B)
(implicit B: Monoid[B]): B = // ..
def foldMapM[G[_], A, B](fa: F[A])
(f: A => G[B])(implicit G: Monad[G], B: Monoid[B]): G[B] = // ..
(multiply)
Domain Model
// a sum type for Currency
sealed trait Currency
case object USD extends Currency
case object AUD extends Currency
case object JPY extends Currency
case object INR extends Currency
// a Money can have denominations in multiple
// currencies
class Money (val items: Map[Currency, BigDecimal]) {
def toBaseCurrency: BigDecimal =
items.foldLeft(BigDecimal(0)) { case (a, (ccy, amount)) =>
a + Money.exchangeRateWithUSD.get(ccy).getOrElse(BigDecimal(1)) * amount
}
def isDebit = toBaseCurrency < 0
}
Domain Model
object Money {
final val zeroMoney =
new Money(Map.empty[Currency, BigDecimal])
// smart constructor
def apply(amount: BigDecimal, ccy: Currency) =
new Money(Map(ccy -> amount))
// concrete implementation: add two Money objects
def add(m: Money, n: Money) = new Money(
(m.items.toList ++ n.items.toList)
.groupBy(_._1)
.map { case (k, v) =>
(k, v.map(_._2).sum)
}
)
// sample implementation
final val exchangeRateWithUSD: Map[Currency, BigDecimal] =
Map(AUD -> 0.76, JPY -> 0.009, INR -> 0.016, USD -> 1.0)
}
concrete implementation
of fusing 2 Maps - can
we generalize it ?
Domain Model
import java.time.OffsetDateTime
// Account with a specific unique account no
case class Account(no: String, name: String, openDate: OffsetDateTime,
closeDate: Option[OffsetDateTime] = None) {
override def equals(o: Any): Boolean = o match {
case Account(`no`, _, _, _) => true
case _ => false
}
override def hashCode() = no. ##
}
// Payment made for a particular Account
case class Payment(account: Account, amount: Money,
dateOfPayment: OffsetDateTime)
Domain Model
import Money._
object Payments {
def creditAmount(p: Payment): Money =
if (p.amount.isDebit) zeroMoney else p.amount
// concrete implementation
def valuation(payments: List[Payment]): Money =
payments.foldLeft(zeroMoney) { (a, e) =>
add(a, creditAmount(e))
}
// concrete implementation that uses concrete methods of List
def maxPayment(payments: List[Payment]): Money =
payments.map(creditAmount).maxBy(_.toBaseCurrency)
// adjust balances and payments
def newBalances(currentBalances: Map[Account, Money],
currentPayments: Map[Account, Money]): Map[Account, Money] = {
// complicated logic that merges the 2 Maps
Map.empty[Account, Money]
}
}
complex implementation
of fusing 2 Maps - can
we generalize it ?
1. similar contract: Is there
any commonality of
behaviors that we can
extract ?
2. both iterate over the
collection and compute
an aggregate
Domain Model
object Money {
final val zeroMoney =
new Money(Map.empty[Currency, BigDecimal])
// smart constructor
def apply(amount: BigDecimal, ccy: Currency) =
new Money(Map(ccy -> amount))
// concrete implementation: add two Money objects
def add(m: Money, n: Money) = new Money(
(m.items.toList ++ n.items.toList)
.groupBy(_._1)
.map { case (k, v) =>
(k, v.map(_._2).sum)
}
)
// sample implementation
final val exchangeRateWithUSD: Map[Currency, BigDecimal] =
Map(AUD -> 0.76, JPY -> 0.009, INR -> 0.016, USD -> 1.0)
}
concrete implementation
of fusing 2 Maps - can
we generalize it ?
Domain Model
object Money {
final val zeroMoney =
new Money(Map.empty[Currency, BigDecimal])
// smart constructor
def apply(amount: BigDecimal, ccy: Currency) =
new Money(Map(ccy -> amount))
// concrete implementation: add two Money objects
def add(m: Money, n: Money) = new Money(
(m.items.toList ++ n.items.toList)
.groupBy(_._1)
.map { case (k, v) =>
(k, v.map(_._2).sum)
}
)
// sample implementation
final val exchangeRateWithUSD: Map[Currency, BigDecimal] =
Map(AUD -> 0.76, JPY -> 0.009, INR -> 0.016, USD -> 1.0)
}
(a) adds 2 Money objects
(b) has to be associative
identity operation
Pattern:
Monoid for Money!
Domain Model
import Money._
object Payments {
def creditAmount(p: Payment): Money =
if (p.amount.isDebit) zeroMoney else p.amount
// concrete implementation
def valuation(payments: List[Payment]): Money =
payments.foldLeft(zeroMoney) { (a, e) =>
add(a, creditAmount(e))
}
// concrete implementation that uses concrete methods of List
def maxPayment(payments: List[Payment]): Money =
payments.map(creditAmount).maxBy(_.toBaseCurrency)
// adjust balances and payments
def newBalances(currentBalances: Map[Account, Money],
currentPayments: Map[Account, Money]): Map[Account, Money] = {
// complicated logic that merges the 2 Maps
Map.empty[Account, Money]
}
}
complex implementation
of fusing 2 Maps - can
we generalize it ?
1. similar contract: Is there
any commonality of
behaviors that we can
extract ?
2. both iterate over the
collection and compute
an aggregate
Domain Model
import Money._
object Payments {
def creditAmount(p: Payment): Money =
if (p.amount.isDebit) zeroMoney else p.amount
// concrete implementation
def valuation(payments: List[Payment]): Money =
payments.foldLeft(zeroMoney) { (a, e) =>
add(a, creditAmount(e))
}
// concrete implementation that uses concrete methods of List
def maxPayment(payments: List[Payment]): Money =
payments.map(creditAmount).maxBy(_.toBaseCurrency)
// adjust balances and payments
def newBalances(currentBalances: Map[Account, Money],
currentPayments: Map[Account, Money]): Map[Account, Money] = {
// complicated logic that merges the 2 Maps
Map.empty[Account, Money]
}
}
2 different ways to combine a
bunch of Money instances
(a) combine to add
(b) combine to find the max
You get a monoid for Map[K, V]
if V has a monoid - part of standard
library.
(a) combine the 2 Maps
Pattern:
Monoid for Money!
Looking Back
• Similar problem
• Different context
• Reuse of the same algebra
• Different concrete instances of the algebra
import Money._
object Payments {
def creditAmount(p: Payment): Money =
if (p.amount.isDebit) zeroMoney else p.amount
// concrete implementation
def valuation(payments: List[Payment]): Money =
payments.foldLeft(zeroMoney) { (a, e) =>
add(a, creditAmount(e))
}
// concrete implementation that uses concrete methods of List
def maxPayment(payments: List[Payment]): Money =
payments.map(creditAmount).maxBy(_.toBaseCurrency)
// adjust balances and payments
def newBalances(currentBalances: Map[Account, Money],
currentPayments: Map[Account, Money]): Map[Account, Money] = {
// complicated logic that merges the 2 Maps
Map.empty[Account, Money]
}
}
Domain Model
• An aggregation that produces
a single result
• Do we really need a List for the
operation that we are doing ?
• Use the least powerful abstraction
that you need
Pattern: Foldable
Abstracting over Structure & Operation
trait Foldable[F[_]] {
def foldleft[A, B](as: F[A], z: B, f: (B, A) => B): B
def foldMap[A, B](as: F[A], f: A => B)(implicit m: Monoid[B]): B =
foldleft(as, m.zero, (b: B, a: A) => m.combine(b, f(a)))
}
def mapReduce[F[_], A, B](as: F[A], f: A => B)
(implicit ff: Foldable[F], m: Monoid[B]) =
ff.foldMap(as, f)
Domain Model
object Payments extends MoneyInstances with Utils {
def creditAmount: Payment => Money = { p =>
if (p.amount.isDebit) zeroMoney else p.amount
}
def valuation(payments: List[Payment]): Money = {
implicit val m: Monoid[Money] = MoneyAddMonoid
mapReduce(payments)(creditAmount)
}
def maxPayment(payments: List[Payment]): Money = {
implicit val m: Monoid[Money] = MoneyOrderMonoid
mapReduce(payments)(creditAmount)
}
def newBalances(currentBalances: Map[Account, Money],
currentPayments: Map[Account, Money]): Map[Account, Money] = {
implicit val m = MoneyAddMonoid
currentBalances |+| currentPayments
}
}
• Completely generic implementation
with Money manipulation logic
moved to the library code
• Reusability FTW
Parametricity
def mapReduce[F[_], A, B](as: F[A], f: A => B)
(implicit ff: Foldable[F], m: Monoid[B]) =
ff.foldMap(as, f)
• Parametric polymorphism
• No dependence on concrete types
• Reusable under multiple implementation context
• Limited implementation possibilities by definition
• Honors the principle of using the least powerful abstraction that works
• The most important virtue of good functional patterns
Domain Model (Handling Domain Validations)
private void validateState() throws ModelCtorException {
ModelCtorException ex = new ModelCtorException();
if (FAILS == Check.optional(fId, Check.range(1,50))) {
ex.add("Id is optional, 1 ..50 chars.");
}
if (FAILS == Check.required(fName, Check.range(2,50))) {
ex.add("Restaurant Name is required, 2 ..50 chars.");
}
if (FAILS == Check.optional(fLocation, Check.range(2,50))) {
ex.add("Location is optional, 2 ..50 chars.");
}
Validator[] priceChecks = {Check.range(ZERO, HUNDRED), Check.numDecimalsAlways(2)};
if (FAILS == Check.optional(fPrice, priceChecks)) {
ex.add("Price is optional, 0.00 to 100.00.");
}
if (FAILS == Check.optional(fComment, Check.range(2,50))) {
ex.add("Comment is optional, 2 ..50 chars.");
}
if ( ! ex.isEmpty() ) throw ex;
}
Domain Model (Managing Configurations)
public Handler getHandler(Config config) throws Exception {
final String defaultTopic = config.getString("default_topic");
boolean propagate = false;
try {
propagate = config.getBoolean("propagate");
} catch (ConfigException.Missing ignored) {
}
if ("null".equals(defaultTopic)) {
log.warn("default topic is "null"; messages will be discarded unless tagged with kt:");
}
final Properties properties = new Properties();
for (Map.Entry<String, ConfigValue> kv : config.getConfig("producer_config").entrySet()) {
properties.put(kv.getKey(), kv.getValue().unwrapped().toString());
}
final String clientId = // ..
// ..
EncryptionConfig encryptionConfig = new EncryptionConfig();
try {
Config encryption = config.getConfig("encryption");
encryptionConfig.encryptionKey = encryption.getString("key");
encryptionConfig.encryptionAlgorithm = encryption.getString("algorithm");
encryptionConfig.encryptionTransformation = encryption.getString("transformation");
encryptionConfig.encryptionProvider = encryption.getString("provider");
} catch (ConfigException.Missing ignored) {
encryptionConfig = null;
}
return new KafkaHandler(clientId, propagate, defaultTopic, producer, encryptionConfig);
}
Antipatterns
• Repetition
• Imperative, not expression based - hence not
composable
• Littered with exception handling code (try/catch) -
violates referential transparency
• Not modular
Domain Model
type ErrorOr[A] = Either[Exception, A]
private def readString(path: String, config: Config): ErrorOr[String] = try {
Either.right(config.getString(path))
} catch {
case ex: Exception => Either.left(ex)
} Step 1: Abstract exceptions with
an algebra. We need to handle
exceptions, but not throw it upstream
case class KafkaSettings(
brokers: String,
zk: String,
fromTopic: String,
toTopic: String,
errorTopic: String
)
Step 2: Use an algebraic data type
for configuration information
Domain Model
type ErrorOr[A] = Either[Exception, A]
private def readString(path: String, config: Config): ErrorOr[String] = try {
Either.right(config.getString(path))
} catch {
case ex: Exception => Either.left(ex)
}
import com.typesafe.config.Config
def fromKafkaConfig(config: Config) = for {
b <- readString("dcos.kafka.brokers", config)
z <- readString("dcos.kafka.zookeeper", config)
f <- readString("dcos.kafka.fromtopic", config)
t <- readString("dcos.kafka.totopic", config)
e <- readString("dcos.kafka.errortopic", config)
} yield KafkaSettings(b, z, f, t, e)
• Algebra of Monad for composition
of readString
• Looks imperative (and hence intuitive)
though in reality it’s an expression
• Reusing algebra and defining implementation
specific context
Domain Model
import com.typesafe.config.Config
def fromKafkaConfig(config: Config): ErrorOr[KafkaSettings] = for {
b <- readString("dcos.kafka.brokers", config)
z <- readString("dcos.kafka.zookeeper", config)
f <- readString("dcos.kafka.fromtopic", config)
t <- readString("dcos.kafka.totopic", config)
e <- readString("dcos.kafka.errortopic", config)
} yield KafkaSettings(b, z, f, t, e)
Repetitions ..
Algebraic Composition
def fromKafkaConfig(config: Config): ErrorOr[KafkaSettings] = for {
b <- readString("dcos.kafka.brokers", config)
z <- readString("dcos.kafka.zookeeper", config)
f <- readString("dcos.kafka.fromtopic", config)
t <- readString("dcos.kafka.totopic", config)
e <- readString("dcos.kafka.errortopic", config)
} yield KafkaSettings(b, z, f, t, e)
Either[Exception, KafkaSettings]
Algebraic Composition
Either[Exception, KafkaSettings]Config =>
def fromKafkaConfig: Config => ErrorOr[KafkaSettings] = (config: Config) => for {
b <- readString("dcos.kafka.brokers", config)
z <- readString("dcos.kafka.zookeeper", config)
f <- readString("dcos.kafka.fromtopic", config)
t <- readString("dcos.kafka.totopic", config)
e <- readString("dcos.kafka.errortopic", config)
} yield KafkaSettings(b, z, f, t, e)
ReaderT[ErrorOr, Config, KafkaSettings]
we want a better abstraction
for reading stuff in
the abstraction needs to
compose with Either
Algebraic Composition
Either[Exception, KafkaSettings]Config =>
def fromKafkaConfig: Config => ErrorOr[KafkaSettings] = (config: Config) => for {
b <- readString("dcos.kafka.brokers", config)
z <- readString("dcos.kafka.zookeeper", config)
f <- readString("dcos.kafka.fromtopic", config)
t <- readString("dcos.kafka.totopic", config)
e <- readString("dcos.kafka.errortopic", config)
} yield KafkaSettings(b, z, f, t, e)
ReaderT[ErrorOr, Config, KafkaSettings]
• An algebra abstracting our earlier
expression
• Does 2 things - the Reader monad
wraps a unary function & the T part
indicating a monad transformer composes
the 2 monads, the Reader and the Either
• ReaderT is also a monad
Algebraic Composition
type ConfigReader[A] = ReaderT[ErrorOr, Config, A]
def fromKafkaConfig: ConfigReader[KafkaSettings] = for {
b <- readString("dcos.kafka.brokers")
z <- readString("dcos.kafka.zookeeper")
f <- readString("dcos.kafka.fromtopic")
t <- readString("dcos.kafka.totopic")
e <- readString("dcos.kafka.errortopic")
} yield KafkaSettings(b, z, f, t, e)
def readString(path: String): ConfigReader[String] =
Kleisli { (config: Config) =>
try {
Either.right(config.getString(path))
} catch {
case ex: Exception => Either.left(ex)
}
}
Functional Patterns
• Reuse of already existing algebra (Reader, Monad,
Either etc.)
• Algebraic composition - form larger patterns from
smaller ones
• Abstraction remains composable
• And modular
Thanks!
Ad

More Related Content

What's hot (20)

Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverse
Luka Jacobowitz
 
Functional and Event Driven - another approach to domain modeling
Functional and Event Driven - another approach to domain modelingFunctional and Event Driven - another approach to domain modeling
Functional and Event Driven - another approach to domain modeling
Debasish Ghosh
 
Testing in the World of Functional Programming
Testing in the World of Functional ProgrammingTesting in the World of Functional Programming
Testing in the World of Functional Programming
Luka Jacobowitz
 
From functional to Reactive - patterns in domain modeling
From functional to Reactive - patterns in domain modelingFrom functional to Reactive - patterns in domain modeling
From functional to Reactive - patterns in domain modeling
Debasish Ghosh
 
Introduction to Functional Programming in JavaScript
Introduction to Functional Programming in JavaScriptIntroduction to Functional Programming in JavaScript
Introduction to Functional Programming in JavaScript
tmont
 
Traversals for all ocasions
Traversals for all ocasionsTraversals for all ocasions
Traversals for all ocasions
Luka Jacobowitz
 
Scala categorytheory
Scala categorytheoryScala categorytheory
Scala categorytheory
Knoldus Inc.
 
Web futures
Web futuresWeb futures
Web futures
Brendan Eich
 
Intro to Functional Programming
Intro to Functional ProgrammingIntro to Functional Programming
Intro to Functional Programming
Hugo Firth
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
Knoldus Inc.
 
Clojure basics
Clojure basicsClojure basics
Clojure basics
Knoldus Inc.
 
Type Parameterization
Type ParameterizationType Parameterization
Type Parameterization
Knoldus Inc.
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
Knoldus Inc.
 
constructors and destructors in c++
constructors and destructors in c++constructors and destructors in c++
constructors and destructors in c++
HalaiHansaika
 
Monoids, monoids, monoids
Monoids, monoids, monoidsMonoids, monoids, monoids
Monoids, monoids, monoids
Luka Jacobowitz
 
Building a Tagless Final DSL for WebGL
Building a Tagless Final DSL for WebGLBuilding a Tagless Final DSL for WebGL
Building a Tagless Final DSL for WebGL
Luka Jacobowitz
 
Effective way to code in Scala
Effective way to code in ScalaEffective way to code in Scala
Effective way to code in Scala
Knoldus Inc.
 
Dependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake PatternDependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake Pattern
Debasish Ghosh
 
Deriving Scalaz
Deriving ScalazDeriving Scalaz
Deriving Scalaz
nkpart
 
Principled Error Handling with FP
Principled Error Handling with FPPrincipled Error Handling with FP
Principled Error Handling with FP
Luka Jacobowitz
 
Oh, All the things you'll traverse
Oh, All the things you'll traverseOh, All the things you'll traverse
Oh, All the things you'll traverse
Luka Jacobowitz
 
Functional and Event Driven - another approach to domain modeling
Functional and Event Driven - another approach to domain modelingFunctional and Event Driven - another approach to domain modeling
Functional and Event Driven - another approach to domain modeling
Debasish Ghosh
 
Testing in the World of Functional Programming
Testing in the World of Functional ProgrammingTesting in the World of Functional Programming
Testing in the World of Functional Programming
Luka Jacobowitz
 
From functional to Reactive - patterns in domain modeling
From functional to Reactive - patterns in domain modelingFrom functional to Reactive - patterns in domain modeling
From functional to Reactive - patterns in domain modeling
Debasish Ghosh
 
Introduction to Functional Programming in JavaScript
Introduction to Functional Programming in JavaScriptIntroduction to Functional Programming in JavaScript
Introduction to Functional Programming in JavaScript
tmont
 
Traversals for all ocasions
Traversals for all ocasionsTraversals for all ocasions
Traversals for all ocasions
Luka Jacobowitz
 
Scala categorytheory
Scala categorytheoryScala categorytheory
Scala categorytheory
Knoldus Inc.
 
Intro to Functional Programming
Intro to Functional ProgrammingIntro to Functional Programming
Intro to Functional Programming
Hugo Firth
 
Functional Programming With Scala
Functional Programming With ScalaFunctional Programming With Scala
Functional Programming With Scala
Knoldus Inc.
 
Type Parameterization
Type ParameterizationType Parameterization
Type Parameterization
Knoldus Inc.
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
Knoldus Inc.
 
constructors and destructors in c++
constructors and destructors in c++constructors and destructors in c++
constructors and destructors in c++
HalaiHansaika
 
Monoids, monoids, monoids
Monoids, monoids, monoidsMonoids, monoids, monoids
Monoids, monoids, monoids
Luka Jacobowitz
 
Building a Tagless Final DSL for WebGL
Building a Tagless Final DSL for WebGLBuilding a Tagless Final DSL for WebGL
Building a Tagless Final DSL for WebGL
Luka Jacobowitz
 
Effective way to code in Scala
Effective way to code in ScalaEffective way to code in Scala
Effective way to code in Scala
Knoldus Inc.
 
Dependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake PatternDependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake Pattern
Debasish Ghosh
 
Deriving Scalaz
Deriving ScalazDeriving Scalaz
Deriving Scalaz
nkpart
 
Principled Error Handling with FP
Principled Error Handling with FPPrincipled Error Handling with FP
Principled Error Handling with FP
Luka Jacobowitz
 

Viewers also liked (7)

The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect System
John De Goes
 
Nelson: Rigorous Deployment for a Functional World
Nelson: Rigorous Deployment for a Functional WorldNelson: Rigorous Deployment for a Functional World
Nelson: Rigorous Deployment for a Functional World
Timothy Perrett
 
Cassandra Fundamentals - C* 2.0
Cassandra Fundamentals - C* 2.0Cassandra Fundamentals - C* 2.0
Cassandra Fundamentals - C* 2.0
Russell Spitzer
 
Airbnb - Braavos - Whered My Money Go
Airbnb - Braavos - Whered My Money GoAirbnb - Braavos - Whered My Money Go
Airbnb - Braavos - Whered My Money Go
Jiang-Ming Yang
 
Real World Serverless
Real World ServerlessReal World Serverless
Real World Serverless
Petr Zapletal
 
Analyzing Functional Programs
Analyzing Functional ProgramsAnalyzing Functional Programs
Analyzing Functional Programs
Dave Cleaver
 
Continuous delivery for machine learning
Continuous delivery for machine learningContinuous delivery for machine learning
Continuous delivery for machine learning
Rajesh Muppalla
 
The Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect SystemThe Design of the Scalaz 8 Effect System
The Design of the Scalaz 8 Effect System
John De Goes
 
Nelson: Rigorous Deployment for a Functional World
Nelson: Rigorous Deployment for a Functional WorldNelson: Rigorous Deployment for a Functional World
Nelson: Rigorous Deployment for a Functional World
Timothy Perrett
 
Cassandra Fundamentals - C* 2.0
Cassandra Fundamentals - C* 2.0Cassandra Fundamentals - C* 2.0
Cassandra Fundamentals - C* 2.0
Russell Spitzer
 
Airbnb - Braavos - Whered My Money Go
Airbnb - Braavos - Whered My Money GoAirbnb - Braavos - Whered My Money Go
Airbnb - Braavos - Whered My Money Go
Jiang-Ming Yang
 
Real World Serverless
Real World ServerlessReal World Serverless
Real World Serverless
Petr Zapletal
 
Analyzing Functional Programs
Analyzing Functional ProgramsAnalyzing Functional Programs
Analyzing Functional Programs
Dave Cleaver
 
Continuous delivery for machine learning
Continuous delivery for machine learningContinuous delivery for machine learning
Continuous delivery for machine learning
Rajesh Muppalla
 
Ad

Similar to Mining Functional Patterns (20)

Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
nebuta
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
nebuta
 
Monads and Monoids by Oleksiy Dyagilev
Monads and Monoids by Oleksiy DyagilevMonads and Monoids by Oleksiy Dyagilev
Monads and Monoids by Oleksiy Dyagilev
JavaDayUA
 
Lecture 3
Lecture 3Lecture 3
Lecture 3
Muhammad Fayyaz
 
Scala collections wizardry - Scalapeño
Scala collections wizardry - ScalapeñoScala collections wizardry - Scalapeño
Scala collections wizardry - Scalapeño
Sagie Davidovich
 
Practical cats
Practical catsPractical cats
Practical cats
Raymond Tay
 
Fuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional ProgrammingFuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional Programming
Shine Xavier
 
Functional Programming Patterns for the Pragmatic Programmer
Functional Programming Patterns for the Pragmatic ProgrammerFunctional Programming Patterns for the Pragmatic Programmer
Functional Programming Patterns for the Pragmatic Programmer
Raúl Raja Martínez
 
List-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic LanguagesList-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic Languages
Wim Vanderbauwhede
 
An introduction to scala
An introduction to scalaAn introduction to scala
An introduction to scala
Mohsen Zainalpour
 
Introducing scala
Introducing scalaIntroducing scala
Introducing scala
Meetu Maltiar
 
Scala Bootcamp 1
Scala Bootcamp 1Scala Bootcamp 1
Scala Bootcamp 1
Knoldus Inc.
 
High-Performance Haskell
High-Performance HaskellHigh-Performance Haskell
High-Performance Haskell
Johan Tibell
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with Scala
Neelkanth Sachdeva
 
Lecture 5: Functional Programming
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional Programming
Eelco Visser
 
From Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risksFrom Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risks
SeniorDevOnly
 
DSL in scala
DSL in scalaDSL in scala
DSL in scala
Xuân Thu Nguyễn
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
Eric Pederson
 
Ten-page Brief Overview of Swift for Scala Developers
Ten-page Brief Overview of Swift for Scala DevelopersTen-page Brief Overview of Swift for Scala Developers
Ten-page Brief Overview of Swift for Scala Developers
ihji
 
Principles of functional progrmming in scala
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scala
ehsoon
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
nebuta
 
Introduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in HaskellIntroduction to ad-3.4, an automatic differentiation library in Haskell
Introduction to ad-3.4, an automatic differentiation library in Haskell
nebuta
 
Monads and Monoids by Oleksiy Dyagilev
Monads and Monoids by Oleksiy DyagilevMonads and Monoids by Oleksiy Dyagilev
Monads and Monoids by Oleksiy Dyagilev
JavaDayUA
 
Scala collections wizardry - Scalapeño
Scala collections wizardry - ScalapeñoScala collections wizardry - Scalapeño
Scala collections wizardry - Scalapeño
Sagie Davidovich
 
Fuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional ProgrammingFuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional Programming
Shine Xavier
 
Functional Programming Patterns for the Pragmatic Programmer
Functional Programming Patterns for the Pragmatic ProgrammerFunctional Programming Patterns for the Pragmatic Programmer
Functional Programming Patterns for the Pragmatic Programmer
Raúl Raja Martínez
 
List-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic LanguagesList-based Monadic Computations for Dynamic Languages
List-based Monadic Computations for Dynamic Languages
Wim Vanderbauwhede
 
High-Performance Haskell
High-Performance HaskellHigh-Performance Haskell
High-Performance Haskell
Johan Tibell
 
Functional programming with Scala
Functional programming with ScalaFunctional programming with Scala
Functional programming with Scala
Neelkanth Sachdeva
 
Lecture 5: Functional Programming
Lecture 5: Functional ProgrammingLecture 5: Functional Programming
Lecture 5: Functional Programming
Eelco Visser
 
From Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risksFrom Java to Scala - advantages and possible risks
From Java to Scala - advantages and possible risks
SeniorDevOnly
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
Eric Pederson
 
Ten-page Brief Overview of Swift for Scala Developers
Ten-page Brief Overview of Swift for Scala DevelopersTen-page Brief Overview of Swift for Scala Developers
Ten-page Brief Overview of Swift for Scala Developers
ihji
 
Principles of functional progrmming in scala
Principles of functional progrmming in scalaPrinciples of functional progrmming in scala
Principles of functional progrmming in scala
ehsoon
 
Ad

More from Debasish Ghosh (9)

Effects, Algebraically Yours using Scala
Effects, Algebraically Yours using ScalaEffects, Algebraically Yours using Scala
Effects, Algebraically Yours using Scala
Debasish Ghosh
 
Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 Way
Debasish Ghosh
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain Modeling
Debasish Ghosh
 
Domain Modeling with Functions - an algebraic approach
Domain Modeling with Functions - an algebraic approachDomain Modeling with Functions - an algebraic approach
Domain Modeling with Functions - an algebraic approach
Debasish Ghosh
 
Functional Patterns in Domain Modeling
Functional Patterns in Domain ModelingFunctional Patterns in Domain Modeling
Functional Patterns in Domain Modeling
Debasish Ghosh
 
Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rules
Debasish Ghosh
 
Big Data - architectural concerns for the new age
Big Data - architectural concerns for the new ageBig Data - architectural concerns for the new age
Big Data - architectural concerns for the new age
Debasish Ghosh
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional World
Debasish Ghosh
 
DSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic modelDSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic model
Debasish Ghosh
 
Effects, Algebraically Yours using Scala
Effects, Algebraically Yours using ScalaEffects, Algebraically Yours using Scala
Effects, Algebraically Yours using Scala
Debasish Ghosh
 
Functional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 WayFunctional Domain Modeling - The ZIO 2 Way
Functional Domain Modeling - The ZIO 2 Way
Debasish Ghosh
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain Modeling
Debasish Ghosh
 
Domain Modeling with Functions - an algebraic approach
Domain Modeling with Functions - an algebraic approachDomain Modeling with Functions - an algebraic approach
Domain Modeling with Functions - an algebraic approach
Debasish Ghosh
 
Functional Patterns in Domain Modeling
Functional Patterns in Domain ModelingFunctional Patterns in Domain Modeling
Functional Patterns in Domain Modeling
Debasish Ghosh
 
Property based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rulesProperty based Testing - generative data & executable domain rules
Property based Testing - generative data & executable domain rules
Debasish Ghosh
 
Big Data - architectural concerns for the new age
Big Data - architectural concerns for the new ageBig Data - architectural concerns for the new age
Big Data - architectural concerns for the new age
Debasish Ghosh
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional World
Debasish Ghosh
 
DSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic modelDSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic model
Debasish Ghosh
 

Recently uploaded (20)

How to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud PerformanceHow to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud Performance
ThousandEyes
 
Expand your AI adoption with AgentExchange
Expand your AI adoption with AgentExchangeExpand your AI adoption with AgentExchange
Expand your AI adoption with AgentExchange
Fexle Services Pvt. Ltd.
 
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
Andre Hora
 
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and CollaborateMeet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Maxim Salnikov
 
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
University of Hawai‘i at Mānoa
 
Adobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest VersionAdobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest Version
kashifyounis067
 
PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025
mu394968
 
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Andre Hora
 
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
ssuserb14185
 
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Orangescrum
 
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Ranjan Baisak
 
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AIScaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
danshalev
 
Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025
kashifyounis067
 
The Significance of Hardware in Information Systems.pdf
The Significance of Hardware in Information Systems.pdfThe Significance of Hardware in Information Systems.pdf
The Significance of Hardware in Information Systems.pdf
drewplanas10
 
Download YouTube By Click 2025 Free Full Activated
Download YouTube By Click 2025 Free Full ActivatedDownload YouTube By Click 2025 Free Full Activated
Download YouTube By Click 2025 Free Full Activated
saniamalik72555
 
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New VersionPixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
saimabibi60507
 
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdfMicrosoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
TechSoup
 
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRYLEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
NidaFarooq10
 
Revolutionizing Residential Wi-Fi PPT.pptx
Revolutionizing Residential Wi-Fi PPT.pptxRevolutionizing Residential Wi-Fi PPT.pptx
Revolutionizing Residential Wi-Fi PPT.pptx
nidhisingh691197
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 
How to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud PerformanceHow to Optimize Your AWS Environment for Improved Cloud Performance
How to Optimize Your AWS Environment for Improved Cloud Performance
ThousandEyes
 
Expand your AI adoption with AgentExchange
Expand your AI adoption with AgentExchangeExpand your AI adoption with AgentExchange
Expand your AI adoption with AgentExchange
Fexle Services Pvt. Ltd.
 
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
TestMigrationsInPy: A Dataset of Test Migrations from Unittest to Pytest (MSR...
Andre Hora
 
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and CollaborateMeet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Meet the Agents: How AI Is Learning to Think, Plan, and Collaborate
Maxim Salnikov
 
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...Exploring Code Comprehension  in Scientific Programming:  Preliminary Insight...
Exploring Code Comprehension in Scientific Programming: Preliminary Insight...
University of Hawai‘i at Mānoa
 
Adobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest VersionAdobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest Version
kashifyounis067
 
PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025
mu394968
 
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Exceptional Behaviors: How Frequently Are They Tested? (AST 2025)
Andre Hora
 
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
ssuserb14185
 
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Orangescrum
 
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Proactive Vulnerability Detection in Source Code Using Graph Neural Networks:...
Ranjan Baisak
 
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AIScaling GraphRAG:  Efficient Knowledge Retrieval for Enterprise AI
Scaling GraphRAG: Efficient Knowledge Retrieval for Enterprise AI
danshalev
 
Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025
kashifyounis067
 
The Significance of Hardware in Information Systems.pdf
The Significance of Hardware in Information Systems.pdfThe Significance of Hardware in Information Systems.pdf
The Significance of Hardware in Information Systems.pdf
drewplanas10
 
Download YouTube By Click 2025 Free Full Activated
Download YouTube By Click 2025 Free Full ActivatedDownload YouTube By Click 2025 Free Full Activated
Download YouTube By Click 2025 Free Full Activated
saniamalik72555
 
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New VersionPixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
saimabibi60507
 
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdfMicrosoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
Microsoft AI Nonprofit Use Cases and Live Demo_2025.04.30.pdf
TechSoup
 
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRYLEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
NidaFarooq10
 
Revolutionizing Residential Wi-Fi PPT.pptx
Revolutionizing Residential Wi-Fi PPT.pptxRevolutionizing Residential Wi-Fi PPT.pptx
Revolutionizing Residential Wi-Fi PPT.pptx
nidhisingh691197
 
Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025Adobe Lightroom Classic Crack FREE Latest link 2025
Adobe Lightroom Classic Crack FREE Latest link 2025
kashifyounis067
 

Mining Functional Patterns

  • 2. Plan today .. • Design Pattern • Algebra • Algebra <=> Functional Patterns • Mining patterns on real world Scala code
  • 3. Code ahead .. Scala code .. .. though the principles apply equally well to any statically typed functional programming language ..
  • 4. Solution to a Problem in Context Design Pattern
  • 5. Solution to a Problem in Context Design Pattern
  • 6. Solution to a Problem in Context Design Pattern
  • 7. Solution to a Problem in Context Design Pattern
  • 8. Solution to a Problem in Context Design Pattern we are given a problemgeneric component (invariant across context of application) context dependent (varies with the context of problem)
  • 9. What is an Algebra ? Algebra is the study of algebraic structures In mathematics, and more specifically in abstract algebra, an algebraic structure is a set (called carrier set or underlying set) with one or more finitary operations defined on it that satisfies a list of axioms - Wikipedia (https://en.wikipedia.org/wiki/Algebraic_structure)
  • 10. Set A ϕ : A × A → A for (a, b) ∈ A ϕ(a, b) a ϕ b given a binary operation for specific a, b or The Algebra of Sets
  • 11. 3 + 2 = 5 7 + 4 = 11 2 + 0 = 2 0 + 6 = 6 8 + 9 = 9 + 8. Binary operation Identity operation Associative operation always produces an integer (closure of operations) One specific instance of the Algebra
  • 12. Set A ϕ : A × A → A given a binary operation (a ϕ b) ϕ c = a ϕ (b ϕ c) associative for (a, b, c) ∈ A Let’s enhance the Algebra ..
  • 13. Set A ϕ : A × A → A given a binary operation (a ϕ b) ϕ c = a ϕ (b ϕ c) associative for (a, b, c) ∈ A The Algebra of Semigroups
  • 14. Set A ϕ : A × A → A given a binary operation (a ϕ b) ϕ c = a ϕ (b ϕ c) associative for (a, b, c) ∈ A a ϕ I = I ϕ a = a for (a, I ) ∈ A identity The Algebra of Monoids
  • 15. Algebra <=> Protocol class Monoid a where mempty :: a mappend :: a -> a -> a
  • 16. Algebra <=> Protocol with Laws class Monoid a where mempty :: a mappend :: a -> a -> a -- Identity laws x <> mempty = x mempty <> x = x -- Associativity (x <> y) <> z = x <> (y <> z)
  • 17. Monoid In Scala trait Semigroup[A] { def combine(x: A, y: A): A } trait Monoid[A] extends Semigroup[A] { def empty: A }
  • 18. Monoid In Scala trait Semigroup[A] { def combine(x: A, y: A): A } trait Monoid[A] extends Semigroup[A] { def empty: A } val intAdditionMonoid: Monoid[Int] = new Monoid[Int] { def empty: Int = 0 def combine(x: Int, y: Int): Int = x + y } • algebra (interface) • reusable • polymorphic • standard library code • instance (implementation) • specific for a datatype val moneyAdditionMonoid: Monoid[Money] = new Monoid[Money] { def empty: Money = ??? def combine(x: Money, y: Money): Money = ??? } • domain specific instance • specific for Money • application library code
  • 19. Monoid In Scala trait Semigroup[A] { def combine(x: A, y: A): A } trait Monoid[A] extends Semigroup[A] { def empty: A } val intAdditionMonoid: Monoid[Int] = new Monoid[Int] { def empty: Int = 0 def combine(x: Int, y: Int): Int = x + y } • algebra (interface) • reusable • polymorphic • standard library code • instance (implementation) • specific for a datatype val moneyAdditionMonoid: Monoid[Money] = new Monoid[Money] { def empty: Money = ??? def combine(x: Money, y: Money): Money = ??? } • domain specific instance • specific for Money • application library code Generic Specific • Specific implementations use the generic protocol/interface • This reusability is enforced by parametricity (no type specific info in the protocol) • Genericity implies reusability
  • 20. Monoid In Scala trait Semigroup[A] { def combine(x: A, y: A): A } trait Monoid[A] extends Semigroup[A] { def empty: A } val intAdditionMonoid: Monoid[Int] = new Monoid[Int] { def empty: Int = 0 def combine(x: Int, y: Int): Int = x + y } • algebra (interface) • reusable • polymorphic • standard library code • instance (implementation) • specific for a datatype val moneyAdditionMonoid: Monoid[Money] = new Monoid[Money] { def empty: Money = ??? def combine(x: Money, y: Money): Money = ??? } • domain specific instance • specific for Money • application library code Pattern Instances generic & reusable context specific
  • 21. Functional Patterns • Generic, reusable algebra • Parametric on types • Clear separation between pattern (algebra) and its instances • Composable through function composition
  • 22. Functional Patterns • Standard vocabulary - people know these terms, know these operations and their types • Rich ecosystem support through standard libraries • Functions defined in only terms of these interfaces / algebra can be reused by application level data types that follow the pattern
  • 23. Functional Patterns - freebies • Given a type that has an instance of a Monoid, if we have a List of such objects, we can combine them for free using the combine function of Monoid.Also note that the behavior of combine is completely polymorphic - depends on the instance of Monoid that you pass in. • Given a typeV that has an instance of a Monoid, Map[K, V] also gets a Monoid. Part of standard library, but as an application developer you get this for free. • .. and there are many such examples ..
  • 24. Functional Patterns - Multiplicative Power Money: Monoid Payment: Monoid Foo: Monoid Bar: Monoid Polymorphic behaviors in the library that expects a Monoid Domain Model Types with Monoid instances def fold[A](fa: F[A]) (implicit A: Monoid[A]): A = // .. def foldMap[A, B](fa: F[A])(f: A => B) (implicit B: Monoid[B]): B = // .. def foldMapM[G[_], A, B](fa: F[A]) (f: A => G[B])(implicit G: Monad[G], B: Monoid[B]): G[B] = // .. (multiply)
  • 25. Domain Model // a sum type for Currency sealed trait Currency case object USD extends Currency case object AUD extends Currency case object JPY extends Currency case object INR extends Currency // a Money can have denominations in multiple // currencies class Money (val items: Map[Currency, BigDecimal]) { def toBaseCurrency: BigDecimal = items.foldLeft(BigDecimal(0)) { case (a, (ccy, amount)) => a + Money.exchangeRateWithUSD.get(ccy).getOrElse(BigDecimal(1)) * amount } def isDebit = toBaseCurrency < 0 }
  • 26. Domain Model object Money { final val zeroMoney = new Money(Map.empty[Currency, BigDecimal]) // smart constructor def apply(amount: BigDecimal, ccy: Currency) = new Money(Map(ccy -> amount)) // concrete implementation: add two Money objects def add(m: Money, n: Money) = new Money( (m.items.toList ++ n.items.toList) .groupBy(_._1) .map { case (k, v) => (k, v.map(_._2).sum) } ) // sample implementation final val exchangeRateWithUSD: Map[Currency, BigDecimal] = Map(AUD -> 0.76, JPY -> 0.009, INR -> 0.016, USD -> 1.0) } concrete implementation of fusing 2 Maps - can we generalize it ?
  • 27. Domain Model import java.time.OffsetDateTime // Account with a specific unique account no case class Account(no: String, name: String, openDate: OffsetDateTime, closeDate: Option[OffsetDateTime] = None) { override def equals(o: Any): Boolean = o match { case Account(`no`, _, _, _) => true case _ => false } override def hashCode() = no. ## } // Payment made for a particular Account case class Payment(account: Account, amount: Money, dateOfPayment: OffsetDateTime)
  • 28. Domain Model import Money._ object Payments { def creditAmount(p: Payment): Money = if (p.amount.isDebit) zeroMoney else p.amount // concrete implementation def valuation(payments: List[Payment]): Money = payments.foldLeft(zeroMoney) { (a, e) => add(a, creditAmount(e)) } // concrete implementation that uses concrete methods of List def maxPayment(payments: List[Payment]): Money = payments.map(creditAmount).maxBy(_.toBaseCurrency) // adjust balances and payments def newBalances(currentBalances: Map[Account, Money], currentPayments: Map[Account, Money]): Map[Account, Money] = { // complicated logic that merges the 2 Maps Map.empty[Account, Money] } } complex implementation of fusing 2 Maps - can we generalize it ? 1. similar contract: Is there any commonality of behaviors that we can extract ? 2. both iterate over the collection and compute an aggregate
  • 29. Domain Model object Money { final val zeroMoney = new Money(Map.empty[Currency, BigDecimal]) // smart constructor def apply(amount: BigDecimal, ccy: Currency) = new Money(Map(ccy -> amount)) // concrete implementation: add two Money objects def add(m: Money, n: Money) = new Money( (m.items.toList ++ n.items.toList) .groupBy(_._1) .map { case (k, v) => (k, v.map(_._2).sum) } ) // sample implementation final val exchangeRateWithUSD: Map[Currency, BigDecimal] = Map(AUD -> 0.76, JPY -> 0.009, INR -> 0.016, USD -> 1.0) } concrete implementation of fusing 2 Maps - can we generalize it ?
  • 30. Domain Model object Money { final val zeroMoney = new Money(Map.empty[Currency, BigDecimal]) // smart constructor def apply(amount: BigDecimal, ccy: Currency) = new Money(Map(ccy -> amount)) // concrete implementation: add two Money objects def add(m: Money, n: Money) = new Money( (m.items.toList ++ n.items.toList) .groupBy(_._1) .map { case (k, v) => (k, v.map(_._2).sum) } ) // sample implementation final val exchangeRateWithUSD: Map[Currency, BigDecimal] = Map(AUD -> 0.76, JPY -> 0.009, INR -> 0.016, USD -> 1.0) } (a) adds 2 Money objects (b) has to be associative identity operation Pattern: Monoid for Money!
  • 31. Domain Model import Money._ object Payments { def creditAmount(p: Payment): Money = if (p.amount.isDebit) zeroMoney else p.amount // concrete implementation def valuation(payments: List[Payment]): Money = payments.foldLeft(zeroMoney) { (a, e) => add(a, creditAmount(e)) } // concrete implementation that uses concrete methods of List def maxPayment(payments: List[Payment]): Money = payments.map(creditAmount).maxBy(_.toBaseCurrency) // adjust balances and payments def newBalances(currentBalances: Map[Account, Money], currentPayments: Map[Account, Money]): Map[Account, Money] = { // complicated logic that merges the 2 Maps Map.empty[Account, Money] } } complex implementation of fusing 2 Maps - can we generalize it ? 1. similar contract: Is there any commonality of behaviors that we can extract ? 2. both iterate over the collection and compute an aggregate
  • 32. Domain Model import Money._ object Payments { def creditAmount(p: Payment): Money = if (p.amount.isDebit) zeroMoney else p.amount // concrete implementation def valuation(payments: List[Payment]): Money = payments.foldLeft(zeroMoney) { (a, e) => add(a, creditAmount(e)) } // concrete implementation that uses concrete methods of List def maxPayment(payments: List[Payment]): Money = payments.map(creditAmount).maxBy(_.toBaseCurrency) // adjust balances and payments def newBalances(currentBalances: Map[Account, Money], currentPayments: Map[Account, Money]): Map[Account, Money] = { // complicated logic that merges the 2 Maps Map.empty[Account, Money] } } 2 different ways to combine a bunch of Money instances (a) combine to add (b) combine to find the max You get a monoid for Map[K, V] if V has a monoid - part of standard library. (a) combine the 2 Maps Pattern: Monoid for Money!
  • 33. Looking Back • Similar problem • Different context • Reuse of the same algebra • Different concrete instances of the algebra
  • 34. import Money._ object Payments { def creditAmount(p: Payment): Money = if (p.amount.isDebit) zeroMoney else p.amount // concrete implementation def valuation(payments: List[Payment]): Money = payments.foldLeft(zeroMoney) { (a, e) => add(a, creditAmount(e)) } // concrete implementation that uses concrete methods of List def maxPayment(payments: List[Payment]): Money = payments.map(creditAmount).maxBy(_.toBaseCurrency) // adjust balances and payments def newBalances(currentBalances: Map[Account, Money], currentPayments: Map[Account, Money]): Map[Account, Money] = { // complicated logic that merges the 2 Maps Map.empty[Account, Money] } } Domain Model • An aggregation that produces a single result • Do we really need a List for the operation that we are doing ? • Use the least powerful abstraction that you need Pattern: Foldable
  • 35. Abstracting over Structure & Operation trait Foldable[F[_]] { def foldleft[A, B](as: F[A], z: B, f: (B, A) => B): B def foldMap[A, B](as: F[A], f: A => B)(implicit m: Monoid[B]): B = foldleft(as, m.zero, (b: B, a: A) => m.combine(b, f(a))) } def mapReduce[F[_], A, B](as: F[A], f: A => B) (implicit ff: Foldable[F], m: Monoid[B]) = ff.foldMap(as, f)
  • 36. Domain Model object Payments extends MoneyInstances with Utils { def creditAmount: Payment => Money = { p => if (p.amount.isDebit) zeroMoney else p.amount } def valuation(payments: List[Payment]): Money = { implicit val m: Monoid[Money] = MoneyAddMonoid mapReduce(payments)(creditAmount) } def maxPayment(payments: List[Payment]): Money = { implicit val m: Monoid[Money] = MoneyOrderMonoid mapReduce(payments)(creditAmount) } def newBalances(currentBalances: Map[Account, Money], currentPayments: Map[Account, Money]): Map[Account, Money] = { implicit val m = MoneyAddMonoid currentBalances |+| currentPayments } } • Completely generic implementation with Money manipulation logic moved to the library code • Reusability FTW
  • 37. Parametricity def mapReduce[F[_], A, B](as: F[A], f: A => B) (implicit ff: Foldable[F], m: Monoid[B]) = ff.foldMap(as, f) • Parametric polymorphism • No dependence on concrete types • Reusable under multiple implementation context • Limited implementation possibilities by definition • Honors the principle of using the least powerful abstraction that works • The most important virtue of good functional patterns
  • 38. Domain Model (Handling Domain Validations) private void validateState() throws ModelCtorException { ModelCtorException ex = new ModelCtorException(); if (FAILS == Check.optional(fId, Check.range(1,50))) { ex.add("Id is optional, 1 ..50 chars."); } if (FAILS == Check.required(fName, Check.range(2,50))) { ex.add("Restaurant Name is required, 2 ..50 chars."); } if (FAILS == Check.optional(fLocation, Check.range(2,50))) { ex.add("Location is optional, 2 ..50 chars."); } Validator[] priceChecks = {Check.range(ZERO, HUNDRED), Check.numDecimalsAlways(2)}; if (FAILS == Check.optional(fPrice, priceChecks)) { ex.add("Price is optional, 0.00 to 100.00."); } if (FAILS == Check.optional(fComment, Check.range(2,50))) { ex.add("Comment is optional, 2 ..50 chars."); } if ( ! ex.isEmpty() ) throw ex; }
  • 39. Domain Model (Managing Configurations) public Handler getHandler(Config config) throws Exception { final String defaultTopic = config.getString("default_topic"); boolean propagate = false; try { propagate = config.getBoolean("propagate"); } catch (ConfigException.Missing ignored) { } if ("null".equals(defaultTopic)) { log.warn("default topic is "null"; messages will be discarded unless tagged with kt:"); } final Properties properties = new Properties(); for (Map.Entry<String, ConfigValue> kv : config.getConfig("producer_config").entrySet()) { properties.put(kv.getKey(), kv.getValue().unwrapped().toString()); } final String clientId = // .. // .. EncryptionConfig encryptionConfig = new EncryptionConfig(); try { Config encryption = config.getConfig("encryption"); encryptionConfig.encryptionKey = encryption.getString("key"); encryptionConfig.encryptionAlgorithm = encryption.getString("algorithm"); encryptionConfig.encryptionTransformation = encryption.getString("transformation"); encryptionConfig.encryptionProvider = encryption.getString("provider"); } catch (ConfigException.Missing ignored) { encryptionConfig = null; } return new KafkaHandler(clientId, propagate, defaultTopic, producer, encryptionConfig); }
  • 40. Antipatterns • Repetition • Imperative, not expression based - hence not composable • Littered with exception handling code (try/catch) - violates referential transparency • Not modular
  • 41. Domain Model type ErrorOr[A] = Either[Exception, A] private def readString(path: String, config: Config): ErrorOr[String] = try { Either.right(config.getString(path)) } catch { case ex: Exception => Either.left(ex) } Step 1: Abstract exceptions with an algebra. We need to handle exceptions, but not throw it upstream case class KafkaSettings( brokers: String, zk: String, fromTopic: String, toTopic: String, errorTopic: String ) Step 2: Use an algebraic data type for configuration information
  • 42. Domain Model type ErrorOr[A] = Either[Exception, A] private def readString(path: String, config: Config): ErrorOr[String] = try { Either.right(config.getString(path)) } catch { case ex: Exception => Either.left(ex) } import com.typesafe.config.Config def fromKafkaConfig(config: Config) = for { b <- readString("dcos.kafka.brokers", config) z <- readString("dcos.kafka.zookeeper", config) f <- readString("dcos.kafka.fromtopic", config) t <- readString("dcos.kafka.totopic", config) e <- readString("dcos.kafka.errortopic", config) } yield KafkaSettings(b, z, f, t, e) • Algebra of Monad for composition of readString • Looks imperative (and hence intuitive) though in reality it’s an expression • Reusing algebra and defining implementation specific context
  • 43. Domain Model import com.typesafe.config.Config def fromKafkaConfig(config: Config): ErrorOr[KafkaSettings] = for { b <- readString("dcos.kafka.brokers", config) z <- readString("dcos.kafka.zookeeper", config) f <- readString("dcos.kafka.fromtopic", config) t <- readString("dcos.kafka.totopic", config) e <- readString("dcos.kafka.errortopic", config) } yield KafkaSettings(b, z, f, t, e) Repetitions ..
  • 44. Algebraic Composition def fromKafkaConfig(config: Config): ErrorOr[KafkaSettings] = for { b <- readString("dcos.kafka.brokers", config) z <- readString("dcos.kafka.zookeeper", config) f <- readString("dcos.kafka.fromtopic", config) t <- readString("dcos.kafka.totopic", config) e <- readString("dcos.kafka.errortopic", config) } yield KafkaSettings(b, z, f, t, e) Either[Exception, KafkaSettings]
  • 45. Algebraic Composition Either[Exception, KafkaSettings]Config => def fromKafkaConfig: Config => ErrorOr[KafkaSettings] = (config: Config) => for { b <- readString("dcos.kafka.brokers", config) z <- readString("dcos.kafka.zookeeper", config) f <- readString("dcos.kafka.fromtopic", config) t <- readString("dcos.kafka.totopic", config) e <- readString("dcos.kafka.errortopic", config) } yield KafkaSettings(b, z, f, t, e) ReaderT[ErrorOr, Config, KafkaSettings] we want a better abstraction for reading stuff in the abstraction needs to compose with Either
  • 46. Algebraic Composition Either[Exception, KafkaSettings]Config => def fromKafkaConfig: Config => ErrorOr[KafkaSettings] = (config: Config) => for { b <- readString("dcos.kafka.brokers", config) z <- readString("dcos.kafka.zookeeper", config) f <- readString("dcos.kafka.fromtopic", config) t <- readString("dcos.kafka.totopic", config) e <- readString("dcos.kafka.errortopic", config) } yield KafkaSettings(b, z, f, t, e) ReaderT[ErrorOr, Config, KafkaSettings] • An algebra abstracting our earlier expression • Does 2 things - the Reader monad wraps a unary function & the T part indicating a monad transformer composes the 2 monads, the Reader and the Either • ReaderT is also a monad
  • 47. Algebraic Composition type ConfigReader[A] = ReaderT[ErrorOr, Config, A] def fromKafkaConfig: ConfigReader[KafkaSettings] = for { b <- readString("dcos.kafka.brokers") z <- readString("dcos.kafka.zookeeper") f <- readString("dcos.kafka.fromtopic") t <- readString("dcos.kafka.totopic") e <- readString("dcos.kafka.errortopic") } yield KafkaSettings(b, z, f, t, e) def readString(path: String): ConfigReader[String] = Kleisli { (config: Config) => try { Either.right(config.getString(path)) } catch { case ex: Exception => Either.left(ex) } }
  • 48. Functional Patterns • Reuse of already existing algebra (Reader, Monad, Either etc.) • Algebraic composition - form larger patterns from smaller ones • Abstraction remains composable • And modular