SlideShare une entreprise Scribd logo
1  sur  95
Télécharger pour lire hors ligne
Functional and Algebraic Domain
Modeling
Debasish Ghosh
@debasishg
関数型、代数的なドメイン・モデリングの方法
Saturday, 30 January 16
Domain Modeling
ドメイン・モデリング
Saturday, 30 January 16
Domain Modeling(Functional)
関数型なドメイン・モデリング
Saturday, 30 January 16
What is a domain model ?
A domain model in problem solving and software engineering is a
conceptual model of all the topics related to a specific problem. It
describes the various entities, their attributes, roles, and
relationships, plus the constraints that govern the problem domain.
It does not describe the solutions to the problem.
Wikipedia (http://en.wikipedia.org/wiki/Domain_model)
特定の問題領域に関する概念モデル
エンティティ/関連/制約などを記述
Saturday, 30 January 16
The Functional Lens ..
“domain API evolution through algebraic
composition”
関数型レンズ
代数的合成を通じたドメイン API の進化
Saturday, 30 January 16
「サーバを関数として考える」
Saturday, 30 January 16
Twitter 社でのサーバソフトウェアの構成は fp と同じ理念
(不変性、関数の合成、副作用の分離)に基づく
Saturday, 30 January 16
Your domain model is a
function
ドメインモデルは関数である
Saturday, 30 January 16
Your domain model is a
function
ドメインモデルは関数(...であって欲しい)
Saturday, 30 January 16
Your domain model is a
collection of functions
ドメインモデルは関数の集合である
Saturday, 30 January 16
Your domain model is a
collection of functions
some simpler models are ..
具体例で考えると...
Saturday, 30 January 16
https://msdn.microsoft.com/en-us/library/jj591560.aspx
カンファレンス管理システム
Saturday, 30 January 16
A Bounded Context
• has a consistent vocabulary
• a set of domain behaviors modeled as
functions on domain objects
implemented as types
• related behaviors grouped as modules
境界づけられたコンテキストは、統一された語彙を持つ
ドメインの振る舞いは関数、オブジェクトは型として実装するSaturday, 30 January 16
Domain Model = ∪(i) Bounded Context(i)
Saturday, 30 January 16
Domain Model = ∪(i) Bounded Context(i)
Bounded Context = { f(x) | p(x) ∈ Domain Rules }
Saturday, 30 January 16
Domain Model = ∪(i) Bounded Context(i)
Bounded Context = { f(x) | p(x) ∈ Domain Rules }
• domain function
• on an object of type x
• composes with other functions
• closed under composition
• business rules
f はドメイン関数で、他の関数と合成できる
p はビジネスルール
Saturday, 30 January 16
• Functions / Morphisms
• Types / Sets
• Composition
• Rules / Laws
関数と射、型と集合、合成、ルールと法則
Saturday, 30 January 16
• Functions / Morphisms
• Types / Sets
• Composition
• Rules / Laws
algebra
要は代数ということ
Saturday, 30 January 16
Domain Model Algebra
ドメインモデルの代数
Saturday, 30 January 16
Domain Model Algebra
(algebra of types, functions & laws)
型と関数と法則の代数
Saturday, 30 January 16
Domain Model Algebra
(algebra of types, functions & laws)
explicit
• types
• type constraints
• expression in terms of other generic algebra
これを明示的にすると、型、型の制約、他の代数を用いた表現
Saturday, 30 January 16
Domain Model Algebra
(algebra of types, functions & laws)
explicit verifiable
• types
• type constraints
• expr in terms of other generic algebra
• type constraints
• more constraints if you have DT
• algebraic property based testing
確認可能なのは型制約、代数的プロパティーベースのテスト
依存型があればより強い制約を検証できる
Saturday, 30 January 16
Problem Domain
問題ドメインの例として証券取引口座を考察する
Saturday, 30 January 16
Bank
Account
Trade
Customer
...
...
...
Problem Domain
...
entities
エンティティとなるのは、口座、顧客、取引、銀行
Saturday, 30 January 16
Bank
Account
Trade
Customer
...
...
...
do trade
process
execution
place
order
Problem Domain
...
entities
behaviors
振る舞いとなるのは、注文、取引、執行処理
Saturday, 30 January 16
Bank
Account
Trade
Customer
...
...
...
do trade
process
execution
place
order
Problem Domain
...
market
regulations
tax laws
brokerage
commission
rates
...
entities
behaviors
laws
法則となるのは株式市場規則、税法、手数料
Saturday, 30 January 16
do trade
process
execution
place
order
Solution Domain
...
behaviors
Functions
(Type => Type)
ソリューションドメインでは、振る舞いは関数 (型 型)
Saturday, 30 January 16
Bank
Account
Trade
Customer
...
...
...
do trade
process
execution
place
order
Solution Domain
...
entities
behaviors
functions
(Type => Type)
algebraic data type
エンティティは代数的データ型
Saturday, 30 January 16
Bank
Account
Trade
Customer
...
...
...
do trade
process
execution
place
order
Solution Domain
...
market
regulations
tax laws
brokerage
commission
rates
...
entities
behaviors
laws
functions
(Type => Type)
algebraic data type business rules / invariants
法則はビジネス・ルールもしくは不変関係
Saturday, 30 January 16
Bank
Account
Trade
Customer
...
...
...
do trade
process
execution
place
order
Solution Domain
...
market
regulations
tax laws
brokerage
commission
rates
...
entities
behaviors
laws
functions
(Type => Type)
algebraic data type business rules / invariants
Monoid
Monad
...
モノイドやモナドといった型クラス
Saturday, 30 January 16
Bank
Account
Trade
Customer
...
...
...
do trade
process
execution
place
order
Solution Domain
...
market
regulations
tax laws
brokerage
commission
rates
...
entities
behaviors
laws
functions
(Type => Type)
algebraic data type business rules / invariants
Monoid
Monad
...
これを全部やるとドメイン代数
Domain Algebra
Saturday, 30 January 16
Domain Model = ∪(i) Bounded Context(i)
Bounded Context = { f(x) | p(x) ∈ Domain Rules }
• domain function
• on an object of type x
• composes with other functions
• closed under composition
• business rules
Domain Algebra
Domain Algebra
「境界づけられたコンテキスト」はドメイン代数のこと
Saturday, 30 January 16
Client places order
- flexible format
1
クライアントが注文を出す
フォーマットは様々
Saturday, 30 January 16
Client places order
- flexible format
Transform to internal domain
model entity and place for execution
1 2
内部でのドメインモデルエンティティに変換して、
実際に注文を出す
Saturday, 30 January 16
Client places order
- flexible format
Transform to internal domain
model entity and place for execution
Trade & Allocate to
client accounts
1 2
3
取引し、結果をクライアントのアカウントに紐づける
Saturday, 30 January 16
def clientOrders: ClientOrderSheet => List[Order]
def execute: Market => Account => Order => List[Execution]
def allocate: List[Account] => Execution => List[Trade]
Saturday, 30 January 16
def clientOrders: ClientOrderSheet => List[Order]
def execute[Account <: BrokerAccount]: Market => Account
=> Order => List[Execution]
def allocate[Account <: TradingAccount]: List[Account]
=> Execution => List[Trade]
Saturday, 30 January 16
def clientOrders: ClientOrderSheet => List[Order]
def execute: Market => Account => Order => List[Execution]
def allocate: List[Account] => Execution => List[Trade]
Types out of thin air No implementation till now
Type names resonate domain language
どこからともなく降ってきた型。今の所実装の話はゼロ。
型の名前はドメイン言語を反映
Saturday, 30 January 16
def clientOrders: ClientOrderSheet => List[Order]
def execute: Market => Account => Order => List[Execution]
def allocate: List[Account] => Execution => List[Trade]
•Types (domain entities)
• Functions operating on types (domain behaviors)
• Laws (business rules)
型 (エンティティ)、関数 (ドメインの振る舞い)、
法則 (ビジネス・ルール)
Saturday, 30 January 16
def clientOrders: ClientOrderSheet => List[Order]
def execute: Market => Account => Order => List[Execution]
def allocate: List[Account] => Execution => List[Trade]
•Types (domain entities)
• Functions operating on types (domain behaviors)
• Laws (business rules)
Algebra of the API
これが API の代数
Saturday, 30 January 16
trait Trading[Account, Trade, ClientOrderSheet, Order,
Execution, Market] {
def clientOrders: ClientOrderSheet => List[Order]
def execute: Market => Account => Order => List[Execution]
def allocate: List[Account] => Execution => List[Trade]
def tradeGeneration(market: Market, broker: Account,
clientAccounts: List[Account]) = ???
}
parameterized on typesmodule
モジュール、型パラメータ
Saturday, 30 January 16
Algebraic Design
• The algebra is the binding contract of the
API
• Implementation is NOT part of the algebra
• An algebra can have multiple interpreters
(aka implementations)
• One of the core principles of functional
programming is to decouple the algebra from
the interpreter
代数的設計手法: 代数は API が準拠する制約
実装は代数に含まれず、実装からは分離されている
Saturday, 30 January 16
def clientOrders: ClientOrderSheet => List[Order]
def execute: Market => Account => Order => List[Execution]
def allocate: List[Account] => Execution => List[Trade]
let’s do some algebra ..
代数の練習
Saturday, 30 January 16
def clientOrders: ClientOrderSheet => List[Order]
def execute(m: Market, broker: Account): Order => List[Execution]
def allocate(accounts: List[Account]): Execution => List[Trade]
let’s do some algebra ..
Saturday, 30 January 16
def clientOrders: ClientOrderSheet => List[Order]
def execute(m: Market, broker: Account): Order => List[Execution]
def allocate(accounts: List[Account]): Execution => List[Trade]
let’s do some algebra ..
Saturday, 30 January 16
def clientOrders: ClientOrderSheet => List[Order]
def execute(m: Market, broker: Account): Order => List[Execution]
def allocate(accounts: List[Account]): Execution => List[Trade]
let’s do some algebra ..
Saturday, 30 January 16
def clientOrders: ClientOrderSheet => List[Order]
def execute(m: Market, broker: Account): Order => List[Execution]
def allocate(accounts: List[Account]): Execution => List[Trade]
let’s do some algebra ..
Saturday, 30 January 16
def clientOrders: ClientOrderSheet => List[Order]
def execute(m: Market, broker: Account): Order => List[Execution]
def allocate(accounts: List[Account]): Execution => List[Trade]
let’s do some algebra ..
Saturday, 30 January 16
def f: A => List[B]
def g: B => List[C]
def h: C => List[D]
.. a problem of composition ..
これは ... 合成の問題だ
Saturday, 30 January 16
.. a problem of
composition with effects ..
def f: A => List[B]
def g: B => List[C]
def h: C => List[D]
これは ... 作用付きの合成の問題だ
Saturday, 30 January 16
def f[M: Monad]: A => M[B]
def g[M: Monad]: B => M[C]
def h[M: Monad]: C => M[D]
.. a problem of composition with
effects that can be generalized ..
これはモナドとして抽象化できる作用付きの合成の問題だ
Saturday, 30 January 16
case class Kleisli[M[_], A, B](run: A => M[B]) {
def andThen[C](f: B => M[C])
(implicit M: Monad[M]): Kleisli[M, A, C] =
Kleisli((a: A) => M.flatMap(run(a))(f))
}
.. function composition with
Effects ..
It’s a Kleisli !
作用付きの関数の合成と言えば、Kleisli!
Saturday, 30 January 16
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
def execute(m: Market, b: Account): Kleisli[List, Order, Execution]
def allocate(acts: List[Account]): Kleisli[List, Execution, Trade]
Follow the types
.. function composition with
Effects ..
def clientOrders: ClientOrderSheet => List[Order]
def execute(m: Market, broker: Account): Order => List[Execution]
def allocate(accounts: List[Account]): Execution => List[Trade]
型に任せて考える
Saturday, 30 January 16
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
def execute(m: Market, b: Account): Kleisli[List, Order, Execution]
def allocate(acts: List[Account]): Kleisli[List, Execution, Trade]
Domain algebra composed with the
categorical algebra of a Kleisli Arrow
.. function composition with
Effects ..
Klieisli 射によって合成されたドメイン代数
Saturday, 30 January 16
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
def execute(m: Market, b: Account): Kleisli[List, Order, Execution]
def allocate(acts: List[Account]): Kleisli[List, Execution, Trade]
.. that implements the semantics of our
domain algebraically ..
.. function composition with
Effects ..
ドメインの意味論を代数的に実装する作用付きの関数の合成
Saturday, 30 January 16
def tradeGeneration(
market: Market,
broker: Account,
clientAccounts: List[Account]) = {
clientOrders andThen
execute(market, broker) andThen
allocate(clientAccounts)
}
Implementation follows the specification
.. the complete trade generation
logic ..
実装は仕様に従う
Saturday, 30 January 16
def tradeGeneration(
market: Market,
broker: Account,
clientAccounts: List[Account]) = {
clientOrders andThen
execute(market, broker) andThen
allocate(clientAccounts)
}
Implementation follows the specification
and we get the Ubiquitous Language for
free :-)
.. the complete trade generation
logic ..
実装は仕様に従い、
そこからユビキタス言語を読み取ることが出来る
Saturday, 30 January 16
algebraic & functional
• Just Pure Functions. Lower cognitive load -
don’t have to think of the classes & data
members where behaviors will reside
• Compositional. Algebras compose - we
defined the algebras of our domain APIs in
terms of existing, time tested algebras of
Kleislis and Monads
代数的かつ関数型の設計は、
純粋関数のみで構成する、合成可能な設計
Saturday, 30 January 16
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
def execute(m: Market, b: Account): Kleisli[List, Order, Execution]
def allocate(acts: List[Account]): Kleisli[List, Execution, Trade]
.. our algebra still doesn’t handle errors
that may occur within our domain
behaviors ..
.. function composition with
Effects ..
そう言えばエラー処理どうする?
Saturday, 30 January 16
more algebra,
more types
代数と型、大盛りで追加!
Saturday, 30 January 16
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
return type constructor
List は戻り値の型コンストラクタ
Saturday, 30 January 16
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
return type constructor
What happens in case the operation fails ?
演算が失敗したらどうなる?
Saturday, 30 January 16
Error handling as an
Effect
• pure and functional
• with an explicit and published algebra
• stackable with existing effects
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
モナド作用としてのエラー処理
純粋で関数型に。明示的な代数。既存の作用と積み上げ可能。
Saturday, 30 January 16
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
.. stacking of effects ..
M[List[_]]
作用の積み上げ
Saturday, 30 January 16
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
.. stacking of effects ..
M[List[_]]: M is a Monad
List をエラー処理のためのモナド M で囲む
Saturday, 30 January 16
type Response[A] = String / Option[A]
val count: Response[Int] = some(10).right
for {
maybeCount <- count
} yield {
for {
c <- maybeCount
// use c
} yield c
}
Monad Transformers
モナド変換子
Saturday, 30 January 16
type Response[A] = String / Option[A]
val count: Response[Int] = some(10).right
for {
maybeCount <- count
} yield {
for {
c <- maybeCount
// use c
} yield c
}
type Error[A] = String / A
type Response[A] = OptionT[Error, A]
val count: Response[Int] = 10.point[Response]
for{
c <- count
// use c : c is an Int here
} yield (())
Monad Transformers
Saturday, 30 January 16
type Response[A] = String / Option[A]
val count: Response[Int] = some(10).right
for {
maybeCount <- count
} yield {
for {
c <- maybeCount
// use c
} yield c
}
type Error[A] = String / A
type Response[A] = OptionT[Error, A]
val count: Response[Int] = 10.point[Response]
for{
c <- count
// use c : c is an Int here
} yield (())
Monad Transformers
richer algebra
代数として扱いやすいのは OptionT を使った方
Saturday, 30 January 16
Monad Transformers
• collapses the stack and gives us a single
monad to deal with
• order of stacking is important though
モナド変換子は積み上げたモナドを一つに潰すことができる
ただし積み上げる順番は大切
Saturday, 30 January 16
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
.. stacking of effects ..
case class ListT[M[_], A] (run: M[List[A]]) { //..
ListT モナド変換子を使う
Saturday, 30 January 16
これは代数にとって小さな一歩だが、
ドメインモデルにとっては巨大な跳躍である
Saturday, 30 January 16
type StringOr[A] = String / A
type Valid[A] = ListT[StringOr, A]
これは代数にとって小さな一歩だが、
ドメインモデルにとっては巨大な跳躍である
Saturday, 30 January 16
type StringOr[A] = String / A
type Valid[A] = ListT[StringOr, A]
def clientOrders: Kleisli[Valid, ClientOrderSheet, Order]
def execute(m: Market, b: Account): Kleisli[Valid, Order, Execution]
def allocate(acts: List[Account]): Kleisli[Valid, Execution, Trade]
これは代数にとって小さな一歩だが、
ドメインモデルにとっては巨大な跳躍である
Saturday, 30 January 16
type StringOr[A] = String / A
type Valid[A] = ListT[StringOr, A]
def clientOrders: Kleisli[Valid, ClientOrderSheet, Order]
def execute(m: Market, b: Account): Kleisli[Valid, Order, Execution]
def allocate(acts: List[Account]): Kleisli[Valid, Execution, Trade]
.. a small change in algebra, a huge step
for our domain model ..
これは代数にとって小さな一歩だが、
ドメインモデルにとっては巨大な跳躍である
Saturday, 30 January 16
def execute(market: Market, brokerAccount: Account) =
kleisli[List, Order, Execution] { order =>
order.items.map { item =>
Execution(brokerAccount, market, ..)
}
}
Saturday, 30 January 16
private def makeExecution(brokerAccount: Account,
item: LineItem, market: Market): String / Execution = //..
def execute(market: Market, brokerAccount: Account) =
kleisli[Valid, Order, Execution] { order =>
listT[StringOr](
order.items.map { item =>
makeExecution(brokerAccount, market, ..)
}.sequenceU
)
}
Saturday, 30 January 16
List
(aggregates)
Algebra of types
型の代数
集約のための List
Saturday, 30 January 16
List
(aggregates)
Disjunction
(error accumulation)
Algebra of types
エラー蓄積のためのDisjunction
Saturday, 30 January 16
List
(aggregates)
Disjunction
(error accumulation)
Kleisli
(dependency injection)
Algebra of types
依存性注入のための Kleisli
Saturday, 30 January 16
List
(aggregates)
Disjunction
(error accumulation)
Kleisli
(dependency injection)
Future
(reactive non-blocking computation)
Algebra of types
リアクティブでノンブロッキングな処理のための Future
Saturday, 30 January 16
List
(aggregates)
Disjunction
(error accumulation)
Kleisli
(dependency injection)
Future
(reactive non-blocking computation)
Algebra of types
Monad
モナド
Saturday, 30 January 16
List
(aggregates)
Disjunction
(error accumulation)
Kleisli
(dependency injection)
Future
(reactive non-blocking computation)
Algebra of types
Monad
Monoid
モノイド
Saturday, 30 January 16
List
(aggregates)
Disjunction
(error accumulation)
Kleisli
(dependency injection)
Future
(reactive non-blocking computation)
Algebra of types
Monad
Monoid
Compositional
合成可能
Saturday, 30 January 16
List
(aggregates)
Disjunction
(error accumulation)
Kleisli
(dependency injection)
Future
(reactive non-blocking computation)
Algebra of types
Monad
Monoid
Offers a suite of functional
combinators
さまざまな関数型コンビネータを提供する
Saturday, 30 January 16
List
(aggregates)
Disjunction
(error accumulation)
Kleisli
(dependency injection)
Future
(reactive non-blocking computation)
Algebra of types
Monad
Monoid
Handles edge cases so your
domain logic remains clean
ドメインロジックを綺麗保てるように、
エッジケースはこっちで処理する
Saturday, 30 January 16
List
(aggregates)
Disjunction
(error accumulation)
Kleisli
(dependency injection)
Future
(reactive non-blocking computation)
Algebra of types
Monad
Monoid
Implicitly encodes quite a bit
of domain rules
暗黙的にかなり多くのドメインルールをエンコードする
Saturday, 30 January 16
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
def execute(m: Market, b: Account): Kleisli[List, Order, Execution]
def allocate(acts: List[Account]): Kleisli[List, Execution, Trade]
.. the algebra ..
代数的な考え方
Saturday, 30 January 16
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
def execute(m: Market, b: Account): Kleisli[List, Order, Execution]
def allocate(acts: List[Account]): Kleisli[List, Execution, Trade]
.. the algebra ..
functions
関数
Saturday, 30 January 16
.. the algebra ..
def clientOrders: Kleisli[List, ClientOrderSheet, Order]
def execute(m: Market, b: Account): Kleisli[List, Order, Execution]
def allocate(acts: List[Account]): Kleisli[List, Execution, Trade]
types
型
Saturday, 30 January 16
.. the algebra ..
composition
def tradeGeneration(market: Market, broker: Account,
clientAccounts: List[Account]) = {
clientOrders andThen
execute(market, broker) andThen
allocate(clientAccounts)
}
合成
Saturday, 30 January 16
.. the algebra ..
trait OrderLaw {
def sizeLaw: Seq[ClientOrder] => Seq[Order] => Boolean =
{ cos => orders =>
cos.size == orders.size
}
def lineItemLaw: Seq[ClientOrder] => Seq[Order] => Boolean =
{ cos => orders =>
cos.map(instrumentsInClientOrder).sum ==
orders.map(_.items.size).sum
}
}
laws of the algebra
(domain rules)
代数の法則
Saturday, 30 January 16
Domain Rules as
Algebraic Properties
• part of the abstraction
• equally important as the actual
abstraction
• verifiable as properties
代数的プロパティとしてのドメインルール
プロパティとして検証可能となる
Saturday, 30 January 16
.. domain rules verification ..
property("Check Client Order laws") =
forAll((cos: Set[ClientOrder]) => {
val orders = for {
os <- clientOrders.run(cos.toList)
} yield os
sizeLaw(cos.toSeq)(orders) == true
lineItemLaw(cos.toSeq)(orders) == true
})
property based testing FTW ..
プロパティベーステスト最強
Saturday, 30 January 16
https://www.manning.com/books/functional-and-reactive-
domain-modeling
本書いてます
Saturday, 30 January 16
ThankYou!
Saturday, 30 January 16

Contenu connexe

Plus de 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 WayDebasish Ghosh
 
Algebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsAlgebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsDebasish Ghosh
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed worldDebasish Ghosh
 
Approximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming ApplicationsApproximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming ApplicationsDebasish Ghosh
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingDebasish Ghosh
 
Architectural Patterns in Building Modular Domain Models
Architectural Patterns in Building Modular Domain ModelsArchitectural Patterns in Building Modular Domain Models
Architectural Patterns in Building Modular Domain ModelsDebasish Ghosh
 
Mining Functional Patterns
Mining Functional PatternsMining Functional Patterns
Mining Functional PatternsDebasish 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 rulesDebasish 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 ageDebasish Ghosh
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional WorldDebasish Ghosh
 

Plus de Debasish Ghosh (10)

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
 
Algebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain ModelsAlgebraic Thinking for Evolution of Pure Functional Domain Models
Algebraic Thinking for Evolution of Pure Functional Domain Models
 
Power of functions in a typed world
Power of functions in a typed worldPower of functions in a typed world
Power of functions in a typed world
 
Approximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming ApplicationsApproximation Data Structures for Streaming Applications
Approximation Data Structures for Streaming Applications
 
Functional and Algebraic Domain Modeling
Functional and Algebraic Domain ModelingFunctional and Algebraic Domain Modeling
Functional and Algebraic Domain Modeling
 
Architectural Patterns in Building Modular Domain Models
Architectural Patterns in Building Modular Domain ModelsArchitectural Patterns in Building Modular Domain Models
Architectural Patterns in Building Modular Domain Models
 
Mining Functional Patterns
Mining Functional PatternsMining Functional Patterns
Mining Functional Patterns
 
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
 
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
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional World
 

Dernier

eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolsosttopstonverter
 
Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024Anthony Dahanne
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesVictoriaMetrics
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfkalichargn70th171
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITmanoharjgpsolutions
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...OnePlan Solutions
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonApplitools
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxRTS corp
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencessuser9e7c64
 
VictoriaMetrics Anomaly Detection Updates: Q1 2024
VictoriaMetrics Anomaly Detection Updates: Q1 2024VictoriaMetrics Anomaly Detection Updates: Q1 2024
VictoriaMetrics Anomaly Detection Updates: Q1 2024VictoriaMetrics
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsJean Silva
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 

Dernier (20)

eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration tools
 
Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 Updates
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Best Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh ITBest Angular 17 Classroom & Online training - Naresh IT
Best Angular 17 Classroom & Online training - Naresh IT
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
Revolutionizing the Digital Transformation Office - Leveraging OnePlan’s AI a...
 
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + KobitonLeveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
Leveraging AI for Mobile App Testing on Real Devices | Applitools + Kobiton
 
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptxThe Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
The Role of IoT and Sensor Technology in Cargo Cloud Solutions.pptx
 
Patterns for automating API delivery. API conference
Patterns for automating API delivery. API conferencePatterns for automating API delivery. API conference
Patterns for automating API delivery. API conference
 
VictoriaMetrics Anomaly Detection Updates: Q1 2024
VictoriaMetrics Anomaly Detection Updates: Q1 2024VictoriaMetrics Anomaly Detection Updates: Q1 2024
VictoriaMetrics Anomaly Detection Updates: Q1 2024
 
Strategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero resultsStrategies for using alternative queries to mitigate zero results
Strategies for using alternative queries to mitigate zero results
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 

Functional and Algebraic Domain Modeling

  • 1. Functional and Algebraic Domain Modeling Debasish Ghosh @debasishg 関数型、代数的なドメイン・モデリングの方法 Saturday, 30 January 16
  • 4. What is a domain model ? A domain model in problem solving and software engineering is a conceptual model of all the topics related to a specific problem. It describes the various entities, their attributes, roles, and relationships, plus the constraints that govern the problem domain. It does not describe the solutions to the problem. Wikipedia (http://en.wikipedia.org/wiki/Domain_model) 特定の問題領域に関する概念モデル エンティティ/関連/制約などを記述 Saturday, 30 January 16
  • 5. The Functional Lens .. “domain API evolution through algebraic composition” 関数型レンズ 代数的合成を通じたドメイン API の進化 Saturday, 30 January 16
  • 7. Twitter 社でのサーバソフトウェアの構成は fp と同じ理念 (不変性、関数の合成、副作用の分離)に基づく Saturday, 30 January 16
  • 8. Your domain model is a function ドメインモデルは関数である Saturday, 30 January 16
  • 9. Your domain model is a function ドメインモデルは関数(...であって欲しい) Saturday, 30 January 16
  • 10. Your domain model is a collection of functions ドメインモデルは関数の集合である Saturday, 30 January 16
  • 11. Your domain model is a collection of functions some simpler models are .. 具体例で考えると... Saturday, 30 January 16
  • 13. A Bounded Context • has a consistent vocabulary • a set of domain behaviors modeled as functions on domain objects implemented as types • related behaviors grouped as modules 境界づけられたコンテキストは、統一された語彙を持つ ドメインの振る舞いは関数、オブジェクトは型として実装するSaturday, 30 January 16
  • 14. Domain Model = ∪(i) Bounded Context(i) Saturday, 30 January 16
  • 15. Domain Model = ∪(i) Bounded Context(i) Bounded Context = { f(x) | p(x) ∈ Domain Rules } Saturday, 30 January 16
  • 16. Domain Model = ∪(i) Bounded Context(i) Bounded Context = { f(x) | p(x) ∈ Domain Rules } • domain function • on an object of type x • composes with other functions • closed under composition • business rules f はドメイン関数で、他の関数と合成できる p はビジネスルール Saturday, 30 January 16
  • 17. • Functions / Morphisms • Types / Sets • Composition • Rules / Laws 関数と射、型と集合、合成、ルールと法則 Saturday, 30 January 16
  • 18. • Functions / Morphisms • Types / Sets • Composition • Rules / Laws algebra 要は代数ということ Saturday, 30 January 16
  • 20. Domain Model Algebra (algebra of types, functions & laws) 型と関数と法則の代数 Saturday, 30 January 16
  • 21. Domain Model Algebra (algebra of types, functions & laws) explicit • types • type constraints • expression in terms of other generic algebra これを明示的にすると、型、型の制約、他の代数を用いた表現 Saturday, 30 January 16
  • 22. Domain Model Algebra (algebra of types, functions & laws) explicit verifiable • types • type constraints • expr in terms of other generic algebra • type constraints • more constraints if you have DT • algebraic property based testing 確認可能なのは型制約、代数的プロパティーベースのテスト 依存型があればより強い制約を検証できる Saturday, 30 January 16
  • 26. Bank Account Trade Customer ... ... ... do trade process execution place order Problem Domain ... market regulations tax laws brokerage commission rates ... entities behaviors laws 法則となるのは株式市場規則、税法、手数料 Saturday, 30 January 16
  • 27. do trade process execution place order Solution Domain ... behaviors Functions (Type => Type) ソリューションドメインでは、振る舞いは関数 (型 型) Saturday, 30 January 16
  • 28. Bank Account Trade Customer ... ... ... do trade process execution place order Solution Domain ... entities behaviors functions (Type => Type) algebraic data type エンティティは代数的データ型 Saturday, 30 January 16
  • 29. Bank Account Trade Customer ... ... ... do trade process execution place order Solution Domain ... market regulations tax laws brokerage commission rates ... entities behaviors laws functions (Type => Type) algebraic data type business rules / invariants 法則はビジネス・ルールもしくは不変関係 Saturday, 30 January 16
  • 30. Bank Account Trade Customer ... ... ... do trade process execution place order Solution Domain ... market regulations tax laws brokerage commission rates ... entities behaviors laws functions (Type => Type) algebraic data type business rules / invariants Monoid Monad ... モノイドやモナドといった型クラス Saturday, 30 January 16
  • 31. Bank Account Trade Customer ... ... ... do trade process execution place order Solution Domain ... market regulations tax laws brokerage commission rates ... entities behaviors laws functions (Type => Type) algebraic data type business rules / invariants Monoid Monad ... これを全部やるとドメイン代数 Domain Algebra Saturday, 30 January 16
  • 32. Domain Model = ∪(i) Bounded Context(i) Bounded Context = { f(x) | p(x) ∈ Domain Rules } • domain function • on an object of type x • composes with other functions • closed under composition • business rules Domain Algebra Domain Algebra 「境界づけられたコンテキスト」はドメイン代数のこと Saturday, 30 January 16
  • 33. Client places order - flexible format 1 クライアントが注文を出す フォーマットは様々 Saturday, 30 January 16
  • 34. Client places order - flexible format Transform to internal domain model entity and place for execution 1 2 内部でのドメインモデルエンティティに変換して、 実際に注文を出す Saturday, 30 January 16
  • 35. Client places order - flexible format Transform to internal domain model entity and place for execution Trade & Allocate to client accounts 1 2 3 取引し、結果をクライアントのアカウントに紐づける Saturday, 30 January 16
  • 36. def clientOrders: ClientOrderSheet => List[Order] def execute: Market => Account => Order => List[Execution] def allocate: List[Account] => Execution => List[Trade] Saturday, 30 January 16
  • 37. def clientOrders: ClientOrderSheet => List[Order] def execute[Account <: BrokerAccount]: Market => Account => Order => List[Execution] def allocate[Account <: TradingAccount]: List[Account] => Execution => List[Trade] Saturday, 30 January 16
  • 38. def clientOrders: ClientOrderSheet => List[Order] def execute: Market => Account => Order => List[Execution] def allocate: List[Account] => Execution => List[Trade] Types out of thin air No implementation till now Type names resonate domain language どこからともなく降ってきた型。今の所実装の話はゼロ。 型の名前はドメイン言語を反映 Saturday, 30 January 16
  • 39. def clientOrders: ClientOrderSheet => List[Order] def execute: Market => Account => Order => List[Execution] def allocate: List[Account] => Execution => List[Trade] •Types (domain entities) • Functions operating on types (domain behaviors) • Laws (business rules) 型 (エンティティ)、関数 (ドメインの振る舞い)、 法則 (ビジネス・ルール) Saturday, 30 January 16
  • 40. def clientOrders: ClientOrderSheet => List[Order] def execute: Market => Account => Order => List[Execution] def allocate: List[Account] => Execution => List[Trade] •Types (domain entities) • Functions operating on types (domain behaviors) • Laws (business rules) Algebra of the API これが API の代数 Saturday, 30 January 16
  • 41. trait Trading[Account, Trade, ClientOrderSheet, Order, Execution, Market] { def clientOrders: ClientOrderSheet => List[Order] def execute: Market => Account => Order => List[Execution] def allocate: List[Account] => Execution => List[Trade] def tradeGeneration(market: Market, broker: Account, clientAccounts: List[Account]) = ??? } parameterized on typesmodule モジュール、型パラメータ Saturday, 30 January 16
  • 42. Algebraic Design • The algebra is the binding contract of the API • Implementation is NOT part of the algebra • An algebra can have multiple interpreters (aka implementations) • One of the core principles of functional programming is to decouple the algebra from the interpreter 代数的設計手法: 代数は API が準拠する制約 実装は代数に含まれず、実装からは分離されている Saturday, 30 January 16
  • 43. def clientOrders: ClientOrderSheet => List[Order] def execute: Market => Account => Order => List[Execution] def allocate: List[Account] => Execution => List[Trade] let’s do some algebra .. 代数の練習 Saturday, 30 January 16
  • 44. def clientOrders: ClientOrderSheet => List[Order] def execute(m: Market, broker: Account): Order => List[Execution] def allocate(accounts: List[Account]): Execution => List[Trade] let’s do some algebra .. Saturday, 30 January 16
  • 45. def clientOrders: ClientOrderSheet => List[Order] def execute(m: Market, broker: Account): Order => List[Execution] def allocate(accounts: List[Account]): Execution => List[Trade] let’s do some algebra .. Saturday, 30 January 16
  • 46. def clientOrders: ClientOrderSheet => List[Order] def execute(m: Market, broker: Account): Order => List[Execution] def allocate(accounts: List[Account]): Execution => List[Trade] let’s do some algebra .. Saturday, 30 January 16
  • 47. def clientOrders: ClientOrderSheet => List[Order] def execute(m: Market, broker: Account): Order => List[Execution] def allocate(accounts: List[Account]): Execution => List[Trade] let’s do some algebra .. Saturday, 30 January 16
  • 48. def clientOrders: ClientOrderSheet => List[Order] def execute(m: Market, broker: Account): Order => List[Execution] def allocate(accounts: List[Account]): Execution => List[Trade] let’s do some algebra .. Saturday, 30 January 16
  • 49. def f: A => List[B] def g: B => List[C] def h: C => List[D] .. a problem of composition .. これは ... 合成の問題だ Saturday, 30 January 16
  • 50. .. a problem of composition with effects .. def f: A => List[B] def g: B => List[C] def h: C => List[D] これは ... 作用付きの合成の問題だ Saturday, 30 January 16
  • 51. def f[M: Monad]: A => M[B] def g[M: Monad]: B => M[C] def h[M: Monad]: C => M[D] .. a problem of composition with effects that can be generalized .. これはモナドとして抽象化できる作用付きの合成の問題だ Saturday, 30 January 16
  • 52. case class Kleisli[M[_], A, B](run: A => M[B]) { def andThen[C](f: B => M[C]) (implicit M: Monad[M]): Kleisli[M, A, C] = Kleisli((a: A) => M.flatMap(run(a))(f)) } .. function composition with Effects .. It’s a Kleisli ! 作用付きの関数の合成と言えば、Kleisli! Saturday, 30 January 16
  • 53. def clientOrders: Kleisli[List, ClientOrderSheet, Order] def execute(m: Market, b: Account): Kleisli[List, Order, Execution] def allocate(acts: List[Account]): Kleisli[List, Execution, Trade] Follow the types .. function composition with Effects .. def clientOrders: ClientOrderSheet => List[Order] def execute(m: Market, broker: Account): Order => List[Execution] def allocate(accounts: List[Account]): Execution => List[Trade] 型に任せて考える Saturday, 30 January 16
  • 54. def clientOrders: Kleisli[List, ClientOrderSheet, Order] def execute(m: Market, b: Account): Kleisli[List, Order, Execution] def allocate(acts: List[Account]): Kleisli[List, Execution, Trade] Domain algebra composed with the categorical algebra of a Kleisli Arrow .. function composition with Effects .. Klieisli 射によって合成されたドメイン代数 Saturday, 30 January 16
  • 55. def clientOrders: Kleisli[List, ClientOrderSheet, Order] def execute(m: Market, b: Account): Kleisli[List, Order, Execution] def allocate(acts: List[Account]): Kleisli[List, Execution, Trade] .. that implements the semantics of our domain algebraically .. .. function composition with Effects .. ドメインの意味論を代数的に実装する作用付きの関数の合成 Saturday, 30 January 16
  • 56. def tradeGeneration( market: Market, broker: Account, clientAccounts: List[Account]) = { clientOrders andThen execute(market, broker) andThen allocate(clientAccounts) } Implementation follows the specification .. the complete trade generation logic .. 実装は仕様に従う Saturday, 30 January 16
  • 57. def tradeGeneration( market: Market, broker: Account, clientAccounts: List[Account]) = { clientOrders andThen execute(market, broker) andThen allocate(clientAccounts) } Implementation follows the specification and we get the Ubiquitous Language for free :-) .. the complete trade generation logic .. 実装は仕様に従い、 そこからユビキタス言語を読み取ることが出来る Saturday, 30 January 16
  • 58. algebraic & functional • Just Pure Functions. Lower cognitive load - don’t have to think of the classes & data members where behaviors will reside • Compositional. Algebras compose - we defined the algebras of our domain APIs in terms of existing, time tested algebras of Kleislis and Monads 代数的かつ関数型の設計は、 純粋関数のみで構成する、合成可能な設計 Saturday, 30 January 16
  • 59. def clientOrders: Kleisli[List, ClientOrderSheet, Order] def execute(m: Market, b: Account): Kleisli[List, Order, Execution] def allocate(acts: List[Account]): Kleisli[List, Execution, Trade] .. our algebra still doesn’t handle errors that may occur within our domain behaviors .. .. function composition with Effects .. そう言えばエラー処理どうする? Saturday, 30 January 16
  • 61. def clientOrders: Kleisli[List, ClientOrderSheet, Order] return type constructor List は戻り値の型コンストラクタ Saturday, 30 January 16
  • 62. def clientOrders: Kleisli[List, ClientOrderSheet, Order] return type constructor What happens in case the operation fails ? 演算が失敗したらどうなる? Saturday, 30 January 16
  • 63. Error handling as an Effect • pure and functional • with an explicit and published algebra • stackable with existing effects def clientOrders: Kleisli[List, ClientOrderSheet, Order] モナド作用としてのエラー処理 純粋で関数型に。明示的な代数。既存の作用と積み上げ可能。 Saturday, 30 January 16
  • 64. def clientOrders: Kleisli[List, ClientOrderSheet, Order] .. stacking of effects .. M[List[_]] 作用の積み上げ Saturday, 30 January 16
  • 65. def clientOrders: Kleisli[List, ClientOrderSheet, Order] .. stacking of effects .. M[List[_]]: M is a Monad List をエラー処理のためのモナド M で囲む Saturday, 30 January 16
  • 66. type Response[A] = String / Option[A] val count: Response[Int] = some(10).right for { maybeCount <- count } yield { for { c <- maybeCount // use c } yield c } Monad Transformers モナド変換子 Saturday, 30 January 16
  • 67. type Response[A] = String / Option[A] val count: Response[Int] = some(10).right for { maybeCount <- count } yield { for { c <- maybeCount // use c } yield c } type Error[A] = String / A type Response[A] = OptionT[Error, A] val count: Response[Int] = 10.point[Response] for{ c <- count // use c : c is an Int here } yield (()) Monad Transformers Saturday, 30 January 16
  • 68. type Response[A] = String / Option[A] val count: Response[Int] = some(10).right for { maybeCount <- count } yield { for { c <- maybeCount // use c } yield c } type Error[A] = String / A type Response[A] = OptionT[Error, A] val count: Response[Int] = 10.point[Response] for{ c <- count // use c : c is an Int here } yield (()) Monad Transformers richer algebra 代数として扱いやすいのは OptionT を使った方 Saturday, 30 January 16
  • 69. Monad Transformers • collapses the stack and gives us a single monad to deal with • order of stacking is important though モナド変換子は積み上げたモナドを一つに潰すことができる ただし積み上げる順番は大切 Saturday, 30 January 16
  • 70. def clientOrders: Kleisli[List, ClientOrderSheet, Order] .. stacking of effects .. case class ListT[M[_], A] (run: M[List[A]]) { //.. ListT モナド変換子を使う Saturday, 30 January 16
  • 72. type StringOr[A] = String / A type Valid[A] = ListT[StringOr, A] これは代数にとって小さな一歩だが、 ドメインモデルにとっては巨大な跳躍である Saturday, 30 January 16
  • 73. type StringOr[A] = String / A type Valid[A] = ListT[StringOr, A] def clientOrders: Kleisli[Valid, ClientOrderSheet, Order] def execute(m: Market, b: Account): Kleisli[Valid, Order, Execution] def allocate(acts: List[Account]): Kleisli[Valid, Execution, Trade] これは代数にとって小さな一歩だが、 ドメインモデルにとっては巨大な跳躍である Saturday, 30 January 16
  • 74. type StringOr[A] = String / A type Valid[A] = ListT[StringOr, A] def clientOrders: Kleisli[Valid, ClientOrderSheet, Order] def execute(m: Market, b: Account): Kleisli[Valid, Order, Execution] def allocate(acts: List[Account]): Kleisli[Valid, Execution, Trade] .. a small change in algebra, a huge step for our domain model .. これは代数にとって小さな一歩だが、 ドメインモデルにとっては巨大な跳躍である Saturday, 30 January 16
  • 75. def execute(market: Market, brokerAccount: Account) = kleisli[List, Order, Execution] { order => order.items.map { item => Execution(brokerAccount, market, ..) } } Saturday, 30 January 16
  • 76. private def makeExecution(brokerAccount: Account, item: LineItem, market: Market): String / Execution = //.. def execute(market: Market, brokerAccount: Account) = kleisli[Valid, Order, Execution] { order => listT[StringOr]( order.items.map { item => makeExecution(brokerAccount, market, ..) }.sequenceU ) } Saturday, 30 January 16
  • 78. List (aggregates) Disjunction (error accumulation) Algebra of types エラー蓄積のためのDisjunction Saturday, 30 January 16
  • 79. List (aggregates) Disjunction (error accumulation) Kleisli (dependency injection) Algebra of types 依存性注入のための Kleisli Saturday, 30 January 16
  • 80. List (aggregates) Disjunction (error accumulation) Kleisli (dependency injection) Future (reactive non-blocking computation) Algebra of types リアクティブでノンブロッキングな処理のための Future Saturday, 30 January 16
  • 81. List (aggregates) Disjunction (error accumulation) Kleisli (dependency injection) Future (reactive non-blocking computation) Algebra of types Monad モナド Saturday, 30 January 16
  • 82. List (aggregates) Disjunction (error accumulation) Kleisli (dependency injection) Future (reactive non-blocking computation) Algebra of types Monad Monoid モノイド Saturday, 30 January 16
  • 83. List (aggregates) Disjunction (error accumulation) Kleisli (dependency injection) Future (reactive non-blocking computation) Algebra of types Monad Monoid Compositional 合成可能 Saturday, 30 January 16
  • 84. List (aggregates) Disjunction (error accumulation) Kleisli (dependency injection) Future (reactive non-blocking computation) Algebra of types Monad Monoid Offers a suite of functional combinators さまざまな関数型コンビネータを提供する Saturday, 30 January 16
  • 85. List (aggregates) Disjunction (error accumulation) Kleisli (dependency injection) Future (reactive non-blocking computation) Algebra of types Monad Monoid Handles edge cases so your domain logic remains clean ドメインロジックを綺麗保てるように、 エッジケースはこっちで処理する Saturday, 30 January 16
  • 86. List (aggregates) Disjunction (error accumulation) Kleisli (dependency injection) Future (reactive non-blocking computation) Algebra of types Monad Monoid Implicitly encodes quite a bit of domain rules 暗黙的にかなり多くのドメインルールをエンコードする Saturday, 30 January 16
  • 87. def clientOrders: Kleisli[List, ClientOrderSheet, Order] def execute(m: Market, b: Account): Kleisli[List, Order, Execution] def allocate(acts: List[Account]): Kleisli[List, Execution, Trade] .. the algebra .. 代数的な考え方 Saturday, 30 January 16
  • 88. def clientOrders: Kleisli[List, ClientOrderSheet, Order] def execute(m: Market, b: Account): Kleisli[List, Order, Execution] def allocate(acts: List[Account]): Kleisli[List, Execution, Trade] .. the algebra .. functions 関数 Saturday, 30 January 16
  • 89. .. the algebra .. def clientOrders: Kleisli[List, ClientOrderSheet, Order] def execute(m: Market, b: Account): Kleisli[List, Order, Execution] def allocate(acts: List[Account]): Kleisli[List, Execution, Trade] types 型 Saturday, 30 January 16
  • 90. .. the algebra .. composition def tradeGeneration(market: Market, broker: Account, clientAccounts: List[Account]) = { clientOrders andThen execute(market, broker) andThen allocate(clientAccounts) } 合成 Saturday, 30 January 16
  • 91. .. the algebra .. trait OrderLaw { def sizeLaw: Seq[ClientOrder] => Seq[Order] => Boolean = { cos => orders => cos.size == orders.size } def lineItemLaw: Seq[ClientOrder] => Seq[Order] => Boolean = { cos => orders => cos.map(instrumentsInClientOrder).sum == orders.map(_.items.size).sum } } laws of the algebra (domain rules) 代数の法則 Saturday, 30 January 16
  • 92. Domain Rules as Algebraic Properties • part of the abstraction • equally important as the actual abstraction • verifiable as properties 代数的プロパティとしてのドメインルール プロパティとして検証可能となる Saturday, 30 January 16
  • 93. .. domain rules verification .. property("Check Client Order laws") = forAll((cos: Set[ClientOrder]) => { val orders = for { os <- clientOrders.run(cos.toList) } yield os sizeLaw(cos.toSeq)(orders) == true lineItemLaw(cos.toSeq)(orders) == true }) property based testing FTW .. プロパティベーステスト最強 Saturday, 30 January 16