SlideShare a Scribd company logo
Final Tagless vs Free Monad
FPure, Kazan, 2019
1
Alexander Granin
graninas@gmail.com
Twitter: @graninas
Plan
● About me
● A Mysterious Software Design
● Final Tagless vs Free Monad
● To Whom It May Concern
● Links
2
About me
Developer Haskell, C++, C#, Python
Worked for Kaspersky Lab, 2GIS, Juspay, Restaumatic, Enecuum
Researcher Functional Programming in C++
Writer Book “Functional Design and Architecture”
Conferences FPConf, C++ Russia, C++ Siberia, Dev2Dev
Meetups LambdaNsk, FProgSpb, DevDay, TechTalks, ...
3
A Mysterious Software Design
4
cartesianclosedcomicro-che.info/ccc/28
Why academia vs engineering battles
are rarely interesting
People familiar with theory
Haskellers Painstream developers
5
cartesianclosedcomicro-che.info/ccc/28
Why academia vs engineering battles
are rarely interesting
People familiar with theory
Haskellers Painstream developers
People working on real problems
Software engineers Mathskellers
Why engineering vs academia battles
are rarely useful
6
Inversion of Control
Why? How? When?
7
Inversion of Control
Why?
Complexity reducing
Abstraction
Separation of concerns
Low coupling
Effects control
Testability
Maintainability
How? When?
8
Inversion of Control
Why?
Complexity reducing
Abstraction
Separation of concerns
Low coupling
Effects control
Testability
Maintainability
How?
Final Tagless
Free Monad
Service Handle Pattern
ReaderT Pattern
...
When?
9
Inversion of Control
Why?
Complexity reducing
Abstraction
Separation of concerns
Low coupling
Effects control
Testability
Maintainability
How?
Final Tagless
Free Monad
Service Handle Pattern
ReaderT Pattern
...
When?
Big applications
Complex domain
Long lifecycle
Team development
Sirius Business™
10
Free Monad
11
data Meteor = Meteor
{ _size :: Int
, _mass :: Int
}
App
State
12
data Meteor = Meteor
{ _size :: Int
, _mass :: Int
}
data Region
= NorthEast
| NorthWest
| SouthEast
| SouthWest
App
State
13
data Meteor = Meteor
{ _size :: Int
, _mass :: Int
}
data Region
= NorthEast
| NorthWest
| SouthEast
| SouthWest
type Meteors = StateVar (Set Meteor)
type Catalogue = Map Region Meteors
App
State
14
data Meteor = Meteor
{ _size :: Int
, _mass :: Int
}
data Region
= NorthEast
| NorthWest
| SouthEast
| SouthWest
type Meteors = StateVar (Set Meteor)
type Catalogue = Map Region Meteors
data AppState = AppState
{ _catalogue :: Catalogue
, _totalMeteors :: StateVar Int
, _channel :: StateVar (Set Meteor)
}
App
State
15
initState :: StateL AppState
initState = do
StateL
App
State
16
initState :: StateL AppState
initState = do
ne <- newVarIO Set.empty
nw <- newVarIO Set.empty
se <- newVarIO Set.empty
sw <- newVarIO Set.empty
let catalogue = Map.fromList
[ (NorthEast, ne)
, (NorthWest, nw)
, (SouthEast, se)
, (SouthWest, sw)
]
StateL
App
State
17
initState :: StateL AppState
initState = do
ne <- newVarIO Set.empty
nw <- newVarIO Set.empty
se <- newVarIO Set.empty
sw <- newVarIO Set.empty
let catalogue = Map.fromList
[ (NorthEast, ne)
, (NorthWest, nw)
, (SouthEast, se)
, (SouthWest, sw)
]
published <- newVarIO Set.empty
total <- newVarIO 0
pure $ AppState catalogue total published
StateL
App
State
18
getRandomMeteor :: Region -> RandomL Meteor
getRandomMeteor region = do
size <- getRandomInt (1, 100)
mass <- getRandomInt (size, size * 100)
pure $ Meteor size mass region
RandomLStateL
App
State
19
getRandomMeteor :: Region -> RandomL Meteor
getRandomMeteor region = do
size <- getRandomInt (1, 100)
mass <- getRandomInt (size, size * 100)
pure $ Meteor size mass region
publishMeteor :: AppState -> Meteor -> StateL ()
publishMeteor st meteor
= modifyVar (_channel st) $ Set.insert meteor
RandomLStateL
App
State
Business
Logic
20
getRandomMeteor :: Region -> RandomL Meteor
getRandomMeteor region = do
size <- getRandomInt (1, 100)
mass <- getRandomInt (size, size * 100)
pure $ Meteor size mass region
publishMeteor :: AppState -> Meteor -> StateL ()
publishMeteor st meteor
= modifyVar (_channel st) $ Set.insert meteor
meteorShower :: AppState -> Region -> LangL ()
meteorShower st region = do
meteor <- evalRandom $ getRandomMeteor region
atomically $ publishMeteor st meteor
logInfo $ "New meteor discovered: " <> show meteor
LoggerL
LangL
RandomLStateL
App
State
Business
Logic
21
meteorsMonitoring :: AppL ()
meteorsMonitoring = do
st <- atomically $ initState
LoggerL
LangL
RandomLStateL
AppL
App
State
Business
Logic
22
meteorsMonitoring :: AppL ()
meteorsMonitoring = do
st <- atomically $ initState
process $ forever $ meteorShower st NorthEast
process $ forever $ meteorShower st NorthWest
process $ forever $ meteorShower st SouthEast
process $ forever $ meteorShower st SouthWest
process $ forever $ meteorCounter st
LoggerL
LangL
RandomLStateL
ProcessL
AppL
App
State
Business
Logic
23
meteorsMonitoring :: AppConfig -> AppL ()
meteorsMonitoring cfg = do
st <- atomically $ initState cfg
process $ forever $ meteorShower st NorthEast
process $ forever $ meteorShower st NorthWest
process $ forever $ meteorShower st SouthEast
process $ forever $ meteorShower st SouthWest
process $ forever $ meteorCounter st
LoggerL
LangL
RandomLStateL
ProcessL
AppL
App
State
Business
Logic
App
Configs
Application
24
meteorsMonitoring :: AppConfig -> AppL ()
meteorsMonitoring cfg = do
st <- atomically $ initState cfg
process $ forever $ meteorShower st NorthEast
process $ forever $ meteorShower st NorthWest
process $ forever $ meteorShower st SouthEast
process $ forever $ meteorShower st SouthWest
process $ forever $ meteorCounter st
main :: IO ()
main = do
loggerRt <- createLoggerRuntime loggerCfg
appRt <- createAppRuntime loggerRt
startApp appRt $ meteorsMonitoring appCfg
LoggerL
LangL
RandomLStateL
ProcessL
AppL
Runtime, Interpreters, Configs, Environment
Application
App
State
Business
Logic
App
Configs
25
Implementation
Effects, Subsystems & Services
(abstracted as Free eDSLs)
Domain & Business Logic
LoggerL
LangL
RandomLStateL
ProcessL
AppL
Runtime, Interpreters, Configs, Environment
Application
App
State
Business
Logic
App
Configs
26
The Only Thing That Matters
LoggerL
LangL
RandomLStateL
ProcessL
AppL
Runtime, Interpreters, Configs, Environment
Application
App
State
Business
Logic
App
Configs
27
Free Monad vs Final Tagless
28
Free Monad vs Final Tagless
Language definition
29
data LoggerF next where
LogMessage :: LogLevel -> Message
-> (() -> next) -> LoggerF next
makeFunctorInstance ''LoggerF
type LoggerL = F LoggerF
class Monad m => LoggerL m where
logMessage :: LogLevel -> Message -> m ()
30
data LoggerF next where
LogMessage :: LogLevel -> Message
-> (() -> next) -> LoggerF next
makeFunctorInstance ''LoggerF
type LoggerL = F LoggerF
data RandomF next where
GetRandomInt :: (Int, Int) -> (Int -> next)
-> RandomF next
makeFunctorInstance ''RandomF
type RandomL = F RandomF
class Monad m => LoggerL m where
logMessage :: LogLevel -> Message -> m ()
class Monad m => RandomL m where
getRandomInt :: (Int, Int) -> m Int
31
data LoggerF next where
LogMessage :: LogLevel -> Message
-> (() -> next) -> LoggerF next
makeFunctorInstance ''LoggerF
type LoggerL = F LoggerF
data RandomF next where
GetRandomInt :: (Int, Int) -> (Int -> next)
-> RandomF next
makeFunctorInstance ''RandomF
type RandomL = F RandomF
data LangF next where
EvalLogger :: LoggerL ()
-> (() -> next) -> LangF next
EvalRandom :: RandomL a
-> (a -> next) -> LangF next
makeFunctorInstance ''LangF
type LangL = F LangF
class Monad m => LoggerL m where
logMessage :: LogLevel -> Message -> m ()
class Monad m => RandomL m where
getRandomInt :: (Int, Int) -> m Int
-- <NOT NEEDED> --
32
data LoggerF next where
LogMessage :: LogLevel -> Message
-> (() -> next) -> LoggerF next
makeFunctorInstance ''LoggerF
type LoggerL = F LoggerF
data RandomF next where
GetRandomInt :: (Int, Int) -> (Int -> next)
-> RandomF next
makeFunctorInstance ''RandomF
type RandomL = F RandomF
data LangF next where
EvalLogger :: LoggerL ()
-> (() -> next) -> LangF next
EvalRandom :: RandomL a
-> (a -> next) -> LangF next
makeFunctorInstance ''LangF
type LangL = F LangF
class Monad m => LoggerL m where
logMessage :: LogLevel -> Message -> m ()
class Monad m => RandomL m where
getRandomInt :: (Int, Int) -> m Int
-- <NOT NEEDED> --
Boilerplate??!
33
data LoggerF next where
LogMessage :: LogLevel -> Message
-> (() -> next) -> LoggerF next
makeFunctorInstance ''LoggerF
type LoggerL = F LoggerF
data RandomF next where
GetRandomInt :: (Int, Int) -> (Int -> next)
-> RandomF next
makeFunctorInstance ''RandomF
type RandomL = F RandomF
data LangF next where
EvalLogger :: LoggerL ()
-> (() -> next) -> LangF next
EvalRandom :: RandomL a
-> (a -> next) -> LangF next
makeFunctorInstance ''LangF
type LangL = F LangF
class Monad m => LoggerL m where
logMessage :: LogLevel -> Message -> m ()
class Monad m => RandomL m where
getRandomInt :: (Int, Int) -> m Int
-- <NOT NEEDED> --
Functors don’t compose?!!
Boilerplate??!
34
data LoggerF next where
LogMessage :: LogLevel -> Message
-> (() -> next) -> LoggerF next
makeFunctorInstance ''LoggerF
type LoggerL = F LoggerF
data RandomF next where
GetRandomInt :: (Int, Int) -> (Int -> next)
-> RandomF next
makeFunctorInstance ''RandomF
type RandomL = F RandomF
data LangF next where
EvalLogger :: LoggerL ()
-> (() -> next) -> LangF next
EvalRandom :: RandomL a
-> (a -> next) -> LangF next
makeFunctorInstance ''LangF
type LangL = F LangF
class Monad m => LoggerL m where
logMessage :: LogLevel -> Message -> m ()
class Monad m => RandomL m where
getRandomInt :: (Int, Int) -> m Int
-- <NOT NEEDED> --
Functors don’t compose?!!
Boilerplate??!
Too complicated!??
35
The Only Thing That Matters
LoggerL
LangL
RandomLStateL
ProcessL
AppL
Runtime, Interpreters, Configs, Environment
Application
App
State
Business
Logic
App
Configs
36
37
Free Monad vs Final Tagless
Interpreters definition
38
interpretRandomF :: RandomF a -> IO a
interpretRandomF (GetRandomInt r n) = ...
runRandomL :: RandomL a -> IO a
runRandomL = foldF interpretRandomF
instance RandomL (ReaderT CoreRuntime m) where
getRandomInt range = liftIO $ randomRIO range
39
interpretRandomF :: RandomF a -> IO a
interpretRandomF (GetRandomInt r n) = ...
runRandomL :: RandomL a -> IO a
runRandomL = foldF interpretRandomF
interpretLoggerF
:: HsLoggerHandle -> LoggerF a -> IO a
interpretLoggerF _ (LogMessage lvl msg n) = ...
runLoggerL
:: HsLoggerHandle -> L.LoggerL () -> IO ()
runLoggerL h = foldF (interpretLoggerF h)
instance RandomL (ReaderT CoreRuntime m) where
getRandomInt range = liftIO $ randomRIO range
instance LoggerL (ReaderT CoreRuntime m) where
logMessage lvl msg = blaBla
40
interpretRandomF :: RandomF a -> IO a
interpretRandomF (GetRandomInt r n) = ...
runRandomL :: RandomL a -> IO a
runRandomL = foldF interpretRandomF
interpretLoggerF
:: HsLoggerHandle -> LoggerF a -> IO a
interpretLoggerF _ (LogMessage lvl msg n) = ...
runLoggerL
:: HsLoggerHandle -> L.LoggerL () -> IO ()
runLoggerL h = foldF (interpretLoggerF h)
interpretLangF :: CoreRuntime -> LangF a -> IO a
interpretLangF coreRt (EvalLogger l n) = ...
interpretLangF coreRt (EvalRandom r n) = ...
runLangL :: CoreRuntime -> LangL a -> IO a
runLangL coreRt = foldF (interpretLangF coreRt)
instance RandomL (ReaderT CoreRuntime m) where
getRandomInt range = liftIO $ randomRIO range
instance LoggerL (ReaderT CoreRuntime m) where
logMessage lvl msg = blaBla
-- <NOT NEEDED> --
41
interpretRandomF :: RandomF a -> IO a
interpretRandomF (GetRandomInt r n) = ...
runRandomL :: RandomL a -> IO a
runRandomL = foldF interpretRandomF
interpretLoggerF
:: HsLoggerHandle -> LoggerF a -> IO a
interpretLoggerF _ (LogMessage lvl msg n) = ...
runLoggerL
:: HsLoggerHandle -> L.LoggerL () -> IO ()
runLoggerL h = foldF (interpretLoggerF h)
interpretLangF :: CoreRuntime -> LangF a -> IO a
interpretLangF coreRt (EvalLogger l n) = ...
interpretLangF coreRt (EvalRandom r n) = ...
runLangL :: CoreRuntime -> LangL a -> IO a
runLangL coreRt = foldF (interpretLangF coreRt)
instance RandomL (ReaderT CoreRuntime m) where
getRandomInt range = liftIO $ randomRIO range
instance LoggerL (ReaderT CoreRuntime m) where
logMessage lvl msg = blaBla
-- <NOT NEEDED> --
Boilerplate??!
42
interpretRandomF :: RandomF a -> IO a
interpretRandomF (GetRandomInt r n) = ...
runRandomL :: RandomL a -> IO a
runRandomL = foldF interpretRandomF
interpretLoggerF
:: HsLoggerHandle -> LoggerF a -> IO a
interpretLoggerF _ (LogMessage lvl msg n) = ...
runLoggerL
:: HsLoggerHandle -> L.LoggerL () -> IO ()
runLoggerL h = foldF (interpretLoggerF h)
interpretLangF :: CoreRuntime -> LangF a -> IO a
interpretLangF coreRt (EvalLogger l n) = ...
interpretLangF coreRt (EvalRandom r n) = ...
runLangL :: CoreRuntime -> LangL a -> IO a
runLangL coreRt = foldF (interpretLangF coreRt)
instance RandomL (ReaderT CoreRuntime m) where
getRandomInt range = liftIO $ randomRIO range
instance LoggerL (ReaderT CoreRuntime m) where
logMessage lvl msg = blaBla
-- <NOT NEEDED> --
Boilerplate??!
Interpreters don’t compose?!!
43
interpretRandomF :: RandomF a -> IO a
interpretRandomF (GetRandomInt r n) = ...
runRandomL :: RandomL a -> IO a
runRandomL = foldF interpretRandomF
interpretLoggerF
:: HsLoggerHandle -> LoggerF a -> IO a
interpretLoggerF _ (LogMessage lvl msg n) = ...
runLoggerL
:: HsLoggerHandle -> L.LoggerL () -> IO ()
runLoggerL h = foldF (interpretLoggerF h)
interpretLangF :: CoreRuntime -> LangF a -> IO a
interpretLangF coreRt (EvalLogger l n) = ...
interpretLangF coreRt (EvalRandom r n) = ...
runLangL :: CoreRuntime -> LangL a -> IO a
runLangL coreRt = foldF (interpretLangF coreRt)
instance RandomL (ReaderT CoreRuntime m) where
getRandomInt range = liftIO $ randomRIO range
instance LoggerL (ReaderT CoreRuntime m) where
logMessage lvl msg = blaBla
-- <NOT NEEDED> --
Boilerplate??!
Interpreters don’t compose?!!
Slow??!!
44
45
46
47
Church Encoded Free
faster than Final Tagless.
48
FT FreeM ChurchM
10 0.155 0.155 0.167
100 0.16 0.16 0.16
1000 0.161 0.176 0.15
10000 0.166 1.448 0.17
100000 0.31 ∞ 0.276
1000000 1.618 ∞ 1.464
10000000 14.781 ∞ 14.528
20000000 35.751 ∞ 29.888
30000000 53.655 ∞ 46.489
FT FreeM ChurchM
10 0.165 0.168 0.162
100 0.166 0.17 0.165
1000 0.17 0.161 0.163
10000 0.174 0.757 0.18
100000 0.258 ∞ 0.307
1000000 1.357 ∞ 1.236
10000000 11.459 ∞ hang
Use logs, log total
Use delays, factor = 0
Use logs, log total
No delays
49
Free Monad vs Final Tagless
Business Logic
50
getRandomMeteor
:: Region -> RandomL Meteor
getRandomMeteor
:: RandomL m => Region -> m Meteor
51
getRandomMeteor
:: Region -> RandomL Meteor
publishMeteor
:: AppState -> Meteor -> StateL ()
getRandomMeteor
:: RandomL m => Region -> m Meteor
publishMeteor
:: AppState -> Meteor -> STM ()
52
getRandomMeteor
:: Region -> RandomL Meteor
publishMeteor
:: AppState -> Meteor -> StateL ()
meteorShower
:: AppState -> Region -> LangL ()
getRandomMeteor
:: RandomL m => Region -> m Meteor
publishMeteor
:: AppState -> Meteor -> STM ()
meteorShower
:: (MonadUnliftIO m, LoggerL m, RandomL m)
=> AppState -> Region -> m ()
53
getRandomMeteor
:: Region -> RandomL Meteor
publishMeteor
:: AppState -> Meteor -> StateL ()
meteorShower
:: AppState -> Region -> LangL ()
meteorsMonitoring
:: AppConfig -> AppL ()
getRandomMeteor
:: RandomL m => Region -> m Meteor
publishMeteor
:: AppState -> Meteor -> STM ()
meteorShower
:: (MonadUnliftIO m, LoggerL m, RandomL m)
=> AppState -> Region -> m ()
meteorsMonitoring
:: (MonadUnliftIO m, ControlFlowL m,
LoggerL m, RandomL m)
=> AppConfig -> m ()
54
getRandomMeteor
:: RandomL m => Region -> m Meteor
publishMeteor
:: AppState -> Meteor -> STM ()
meteorShower
:: (MonadUnliftIO m, LoggerL m, RandomL m)
=> AppState -> Region -> m ()
meteorsMonitoring
:: (MonadUnliftIO m, ControlFlowL m,
LoggerL m, RandomL m)
=> AppConfig -> m ()
55
Boilerplate.
getRandomMeteor
:: RandomL m => Region -> m Meteor
publishMeteor
:: AppState -> Meteor -> STM ()
meteorShower
:: (MonadUnliftIO m, LoggerL m, RandomL m)
=> AppState -> Region -> m ()
meteorsMonitoring
:: (MonadUnliftIO m, ControlFlowL m,
LoggerL m, RandomL m)
=> AppConfig -> m ()
Boilerplate.
Maintenance nightmare.
56
getRandomMeteor
:: RandomL m => Region -> m Meteor
publishMeteor
:: AppState -> Meteor -> STM ()
meteorShower
:: (MonadUnliftIO m, LoggerL m, RandomL m,
HasCoreRuntime m)
=> AppState -> Region -> m ()
meteorsMonitoring
:: (MonadUnliftIO m, ControlFlowL m,
LoggerL m, RandomL m, HasCoreRuntime m)
=> AppConfig -> m ()
Maintenance nightmare.
Boilerplate.
Implementation details.
57
getRandomMeteor
:: (MonadUnliftIO m, RandomL m)
=> Region -> m Meteor
publishMeteor
:: AppState -> Meteor -> STM ()
meteorShower
:: (MonadUnliftIO m, LoggerL m, RandomL m,
HasCoreRuntime m)
=> AppState -> Region -> m ()
meteorsMonitoring
:: (MonadUnliftIO m, ControlFlowL m,
LoggerL m, RandomL m, HasCoreRuntime m)
=> AppConfig -> m ()
Maintenance nightmare.
Boilerplate.
Illusion of control.
Implementation details.
58
getRandomMeteor
:: Region -> AppEff Meteor
publishMeteor
:: AppState -> Meteor -> STM ()
meteorShower
:: AppState -> Region -> AppEff ()
meteorsMonitoring
:: AppConfig -> AppEff ()
type Eff =
( MonadUnliftIO m
, ControlFlowL m
, LoggerL m
, RandomL m
)
newtype AppEff a = AppT
{ unAppT :: ReaderT CoreRuntime Eff a
}
deriving (Functor, Applicative, Monad)
59
LoggerL
RandomL
MonadUnliftIO
ControlFlowL
STMDatabaseL
UnpredictedRandomEffect
LaunchRockets
LoggerL
LangL
RandomLStateL
ProcessL
AppL
Runtime, Interpreters, Configs, Environment
Application
App
State
Business
Logic
App
Configs
Runtime
DatabaseL
IOL
Business
Logic
App State
App Configs
60
61
Effect system != Layering.
62
Effect system != Layering.
Effect systems is an exceptionally bad idea which could
only have originated in academia.
To Whom It May Concern
63
Functors of free monads aren’t composable.
64
Functors of free monads aren’t composable.
Interpreters of free monads aren’t composable.
65
Functors of free monads aren’t composable.
Interpreters of free monads aren’t composable.
Free monads aren’t composable.
66
Functors of free monads aren’t composable.
Interpreters of free monads aren’t composable.
Free monads aren’t composable.
Free monads are slow.
67
Functors of free monads aren’t composable.
Interpreters of free monads aren’t composable.
Free monads aren’t composable.
Free monads are slow.
Essentially, Free Monads are equivalent to Final Tagles.
68
Functors of free monads aren’t composable.
Interpreters of free monads aren’t composable.
Free monads aren’t composable.
Free monads are slow.
Essentially, Free Monads are equivalent to Final Tagles.
This paper says it’s impossible.
69
Functors of free monads aren’t composable.
Interpreters of free monads aren’t composable.
Free monads aren’t composable.
Free monads are slow.
Essentially, Free Monads are equivalent to Final Tagles.
This paper says it’s impossible.
This paper says it’s bad.
70
Functors of free monads aren’t composable.
Interpreters of free monads aren’t composable.
Free monads aren’t composable.
Free monads are slow.
Essentially, Free Monads are equivalent to Final Tagles.
This paper says it’s impossible.
This paper says it’s bad.
You haven’t read the X’s paper, how dare you?!
71
Software development is not “Math”.
Software development is “Physics”.
In here, experiment is the only measure of truth.
72
Links
Code Hydra framework
My book Functional Design and Architecture
Book’s Patreon Patreon/functional_design_and_architecture
My other talks https://graninas.com/talks-eng
My poetry ;) https://graninas.com/creations/#poetry
73
Free monads are powerful and fast.
FPure, Kazan, 2019
74
Alexander Granin
graninas@gmail.com
Twitter: @graninas

More Related Content

What's hot

Data structures stacks
Data structures   stacksData structures   stacks
Data structures stacks
maamir farooq
 
Stack data structure
Stack data structureStack data structure
Stack data structure
rogineojerio020496
 
Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift
Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwiftSwift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift
Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift
Aaron Douglas
 
The algebra of library design
The algebra of library designThe algebra of library design
The algebra of library design
Leonardo Borges
 
The Ring programming language version 1.5.3 book - Part 87 of 184
The Ring programming language version 1.5.3 book - Part 87 of 184The Ring programming language version 1.5.3 book - Part 87 of 184
The Ring programming language version 1.5.3 book - Part 87 of 184
Mahmoud Samir Fayed
 
Stack using Array
Stack using ArrayStack using Array
Stack using Array
Sayantan Sur
 
Stack Data Structure V1.0
Stack Data Structure V1.0Stack Data Structure V1.0
Stack Data Structure V1.0
Zidny Nafan
 
Stack
StackStack
NetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionNetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf Edition
Paulo Morgado
 
Computer notes - Hashing
Computer notes - HashingComputer notes - Hashing
Computer notes - Hashing
ecomputernotes
 
Stack using Linked List
Stack using Linked ListStack using Linked List
Stack using Linked List
Sayantan Sur
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4Abed Bukhari
 
The Ring programming language version 1.5.3 book - Part 89 of 184
The Ring programming language version 1.5.3 book - Part 89 of 184The Ring programming language version 1.5.3 book - Part 89 of 184
The Ring programming language version 1.5.3 book - Part 89 of 184
Mahmoud Samir Fayed
 
03 stacks and_queues_using_arrays
03 stacks and_queues_using_arrays03 stacks and_queues_using_arrays
03 stacks and_queues_using_arraystameemyousaf
 
Ds stack 03
Ds stack 03Ds stack 03
Ds stack 03
MuhammadZubair568
 
Reactive Programming with RxSwift
Reactive Programming with RxSwiftReactive Programming with RxSwift
Reactive Programming with RxSwift
Scott Gardner
 
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftReactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwift
Florent Pillet
 
Agile Iphone Development
Agile Iphone DevelopmentAgile Iphone Development
Agile Iphone Development
Giordano Scalzo
 
Load-time Hacking using LD_PRELOAD
Load-time Hacking using LD_PRELOADLoad-time Hacking using LD_PRELOAD
Load-time Hacking using LD_PRELOAD
Dharmalingam Ganesan
 

What's hot (20)

Data structures stacks
Data structures   stacksData structures   stacks
Data structures stacks
 
Stack data structure
Stack data structureStack data structure
Stack data structure
 
Stack queue
Stack queueStack queue
Stack queue
 
Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift
Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwiftSwift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift
Swift & ReactiveX – Asynchronous Event-Based Funsies with RxSwift
 
The algebra of library design
The algebra of library designThe algebra of library design
The algebra of library design
 
The Ring programming language version 1.5.3 book - Part 87 of 184
The Ring programming language version 1.5.3 book - Part 87 of 184The Ring programming language version 1.5.3 book - Part 87 of 184
The Ring programming language version 1.5.3 book - Part 87 of 184
 
Stack using Array
Stack using ArrayStack using Array
Stack using Array
 
Stack Data Structure V1.0
Stack Data Structure V1.0Stack Data Structure V1.0
Stack Data Structure V1.0
 
Stack
StackStack
Stack
 
NetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionNetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf Edition
 
Computer notes - Hashing
Computer notes - HashingComputer notes - Hashing
Computer notes - Hashing
 
Stack using Linked List
Stack using Linked ListStack using Linked List
Stack using Linked List
 
Whats new in_csharp4
Whats new in_csharp4Whats new in_csharp4
Whats new in_csharp4
 
The Ring programming language version 1.5.3 book - Part 89 of 184
The Ring programming language version 1.5.3 book - Part 89 of 184The Ring programming language version 1.5.3 book - Part 89 of 184
The Ring programming language version 1.5.3 book - Part 89 of 184
 
03 stacks and_queues_using_arrays
03 stacks and_queues_using_arrays03 stacks and_queues_using_arrays
03 stacks and_queues_using_arrays
 
Ds stack 03
Ds stack 03Ds stack 03
Ds stack 03
 
Reactive Programming with RxSwift
Reactive Programming with RxSwiftReactive Programming with RxSwift
Reactive Programming with RxSwift
 
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftReactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwift
 
Agile Iphone Development
Agile Iphone DevelopmentAgile Iphone Development
Agile Iphone Development
 
Load-time Hacking using LD_PRELOAD
Load-time Hacking using LD_PRELOADLoad-time Hacking using LD_PRELOAD
Load-time Hacking using LD_PRELOAD
 

Similar to Final tagless vs free monad

Hierarchical free monads and software design in fp
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fp
Alexander Granin
 
Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stm
Alexander Granin
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
John De Goes
 
Functors, applicatives, monads
Functors, applicatives, monadsFunctors, applicatives, monads
Functors, applicatives, monads
rkaippully
 
(1) c sharp introduction_basics_dot_net
(1) c sharp introduction_basics_dot_net(1) c sharp introduction_basics_dot_net
(1) c sharp introduction_basics_dot_net
Nico Ludwig
 
New Functional Features of Java 8
New Functional Features of Java 8New Functional Features of Java 8
New Functional Features of Java 8
franciscoortin
 
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
Functional Thursday
 
Intro to functional programming - Confoo
Intro to functional programming - ConfooIntro to functional programming - Confoo
Intro to functional programming - Confoo
felixtrepanier
 
Transition graph using free monads and existentials
Transition graph using free monads and existentialsTransition graph using free monads and existentials
Transition graph using free monads and existentials
Alexander Granin
 
Free Monads Getting Started
Free Monads Getting StartedFree Monads Getting Started
Free Monads Getting Started
Kent Ohashi
 
Harnessing the Power of Java 8 Streams
Harnessing the Power of Java 8 Streams Harnessing the Power of Java 8 Streams
Harnessing the Power of Java 8 Streams
IndicThreads
 
Python na Infraestrutura 
MySQL do Facebook

Python na Infraestrutura 
MySQL do Facebook
Python na Infraestrutura 
MySQL do Facebook

Python na Infraestrutura 
MySQL do Facebook

Artur Rodrigues
 
The... Wonderful? World of Lambdas
The... Wonderful? World of LambdasThe... Wonderful? World of Lambdas
The... Wonderful? World of Lambdas
Esther Lozano
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
John De Goes
 
PyData Paris 2015 - Track 1.1 Alexandre Gramfort
PyData Paris 2015 - Track 1.1 Alexandre GramfortPyData Paris 2015 - Track 1.1 Alexandre Gramfort
PyData Paris 2015 - Track 1.1 Alexandre Gramfort
Pôle Systematic Paris-Region
 
Real Time Big Data Management
Real Time Big Data ManagementReal Time Big Data Management
Real Time Big Data Management
Albert Bifet
 
Flying Futures at the same sky can make the sun rise at midnight
Flying Futures at the same sky can make the sun rise at midnightFlying Futures at the same sky can make the sun rise at midnight
Flying Futures at the same sky can make the sun rise at midnight
Wiem Zine Elabidine
 
Computer notes - Sorting
Computer notes  - SortingComputer notes  - Sorting
Computer notes - Sorting
ecomputernotes
 
Monadic parsers in C++
Monadic parsers in C++Monadic parsers in C++
Monadic parsers in C++
Alexander Granin
 
Meta-objective Lisp @名古屋 Reject 会議
Meta-objective Lisp @名古屋 Reject 会議Meta-objective Lisp @名古屋 Reject 会議
Meta-objective Lisp @名古屋 Reject 会議dico_leque
 

Similar to Final tagless vs free monad (20)

Hierarchical free monads and software design in fp
Hierarchical free monads and software design in fpHierarchical free monads and software design in fp
Hierarchical free monads and software design in fp
 
Concurrent applications with free monads and stm
Concurrent applications with free monads and stmConcurrent applications with free monads and stm
Concurrent applications with free monads and stm
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
 
Functors, applicatives, monads
Functors, applicatives, monadsFunctors, applicatives, monads
Functors, applicatives, monads
 
(1) c sharp introduction_basics_dot_net
(1) c sharp introduction_basics_dot_net(1) c sharp introduction_basics_dot_net
(1) c sharp introduction_basics_dot_net
 
New Functional Features of Java 8
New Functional Features of Java 8New Functional Features of Java 8
New Functional Features of Java 8
 
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
[FT-11][suhorng] “Poor Man's” Undergraduate Compilers
 
Intro to functional programming - Confoo
Intro to functional programming - ConfooIntro to functional programming - Confoo
Intro to functional programming - Confoo
 
Transition graph using free monads and existentials
Transition graph using free monads and existentialsTransition graph using free monads and existentials
Transition graph using free monads and existentials
 
Free Monads Getting Started
Free Monads Getting StartedFree Monads Getting Started
Free Monads Getting Started
 
Harnessing the Power of Java 8 Streams
Harnessing the Power of Java 8 Streams Harnessing the Power of Java 8 Streams
Harnessing the Power of Java 8 Streams
 
Python na Infraestrutura 
MySQL do Facebook

Python na Infraestrutura 
MySQL do Facebook
Python na Infraestrutura 
MySQL do Facebook

Python na Infraestrutura 
MySQL do Facebook

 
The... Wonderful? World of Lambdas
The... Wonderful? World of LambdasThe... Wonderful? World of Lambdas
The... Wonderful? World of Lambdas
 
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
The Easy-Peasy-Lemon-Squeezy, Statically-Typed, Purely Functional Programming...
 
PyData Paris 2015 - Track 1.1 Alexandre Gramfort
PyData Paris 2015 - Track 1.1 Alexandre GramfortPyData Paris 2015 - Track 1.1 Alexandre Gramfort
PyData Paris 2015 - Track 1.1 Alexandre Gramfort
 
Real Time Big Data Management
Real Time Big Data ManagementReal Time Big Data Management
Real Time Big Data Management
 
Flying Futures at the same sky can make the sun rise at midnight
Flying Futures at the same sky can make the sun rise at midnightFlying Futures at the same sky can make the sun rise at midnight
Flying Futures at the same sky can make the sun rise at midnight
 
Computer notes - Sorting
Computer notes  - SortingComputer notes  - Sorting
Computer notes - Sorting
 
Monadic parsers in C++
Monadic parsers in C++Monadic parsers in C++
Monadic parsers in C++
 
Meta-objective Lisp @名古屋 Reject 会議
Meta-objective Lisp @名古屋 Reject 会議Meta-objective Lisp @名古屋 Reject 会議
Meta-objective Lisp @名古屋 Reject 会議
 

More from Alexander Granin

The present and the future of functional programming in c++
The present and the future of functional programming in c++The present and the future of functional programming in c++
The present and the future of functional programming in c++
Alexander Granin
 
О разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentО разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop development
Alexander Granin
 
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Alexander Granin
 
Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...
Alexander Granin
 
Закон Деметры / Demetra's law
Закон Деметры / Demetra's lawЗакон Деметры / Demetra's law
Закон Деметры / Demetra's law
Alexander Granin
 
Design of big applications in FP
Design of big applications in FPDesign of big applications in FP
Design of big applications in FP
Alexander Granin
 
GitHub - зеркало разработчика
GitHub - зеркало разработчикаGitHub - зеркало разработчика
GitHub - зеркало разработчика
Alexander Granin
 
The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++
Alexander Granin
 
Functional programming in C++ LambdaNsk
Functional programming in C++ LambdaNskFunctional programming in C++ LambdaNsk
Functional programming in C++ LambdaNsk
Alexander Granin
 
Software transactional memory. pure functional approach
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approach
Alexander Granin
 
Вы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPВы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FP
Alexander Granin
 
Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonads
Alexander Granin
 
Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++
Alexander Granin
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
Alexander Granin
 
Линзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция данными
Alexander Granin
 
Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)
Alexander Granin
 
Идиоматичный функциональный код
Идиоматичный функциональный кодИдиоматичный функциональный код
Идиоматичный функциональный код
Alexander Granin
 
Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++
Alexander Granin
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
Alexander Granin
 
Профессиональная разработка в суровом Enterprise
Профессиональная разработка в суровом EnterpriseПрофессиональная разработка в суровом Enterprise
Профессиональная разработка в суровом Enterprise
Alexander Granin
 

More from Alexander Granin (20)

The present and the future of functional programming in c++
The present and the future of functional programming in c++The present and the future of functional programming in c++
The present and the future of functional programming in c++
 
О разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop developmentО разработке десктопных приложений / About desktop development
О разработке десктопных приложений / About desktop development
 
Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...Принципы и практики разработки ПО 2 / Principles and practices of software de...
Принципы и практики разработки ПО 2 / Principles and practices of software de...
 
Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...Принципы и практики разработки ПО / Principles and practices of software deve...
Принципы и практики разработки ПО / Principles and practices of software deve...
 
Закон Деметры / Demetra's law
Закон Деметры / Demetra's lawЗакон Деметры / Demetra's law
Закон Деметры / Demetra's law
 
Design of big applications in FP
Design of big applications in FPDesign of big applications in FP
Design of big applications in FP
 
GitHub - зеркало разработчика
GitHub - зеркало разработчикаGitHub - зеркало разработчика
GitHub - зеркало разработчика
 
The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++The Present and The Future of Functional Programming in C++
The Present and The Future of Functional Programming in C++
 
Functional programming in C++ LambdaNsk
Functional programming in C++ LambdaNskFunctional programming in C++ LambdaNsk
Functional programming in C++ LambdaNsk
 
Software transactional memory. pure functional approach
Software transactional memory. pure functional approachSoftware transactional memory. pure functional approach
Software transactional memory. pure functional approach
 
Вы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FPВы не понимаете ФП / You don't understand FP
Вы не понимаете ФП / You don't understand FP
 
Functional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonadsFunctional "Life": parallel cellular automata and comonads
Functional "Life": parallel cellular automata and comonads
 
Functional microscope - Lenses in C++
Functional microscope - Lenses in C++Functional microscope - Lenses in C++
Functional microscope - Lenses in C++
 
Дизайн больших приложений в ФП
Дизайн больших приложений в ФПДизайн больших приложений в ФП
Дизайн больших приложений в ФП
 
Линзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция даннымиЛинзы - комбинаторная манипуляция данными
Линзы - комбинаторная манипуляция данными
 
Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)Линзы - комбинаторная манипуляция данными (Dev2Dev)
Линзы - комбинаторная манипуляция данными (Dev2Dev)
 
Идиоматичный функциональный код
Идиоматичный функциональный кодИдиоматичный функциональный код
Идиоматичный функциональный код
 
Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++Функционально декларативный дизайн на C++
Функционально декларативный дизайн на C++
 
Back to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодняBack to the future: Функциональное программирование вчера и сегодня
Back to the future: Функциональное программирование вчера и сегодня
 
Профессиональная разработка в суровом Enterprise
Профессиональная разработка в суровом EnterpriseПрофессиональная разработка в суровом Enterprise
Профессиональная разработка в суровом Enterprise
 

Recently uploaded

Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
Max Andersen
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
Rakesh Kumar R
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
Boni García
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
Adele Miller
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Crescat
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Neo4j
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
pavan998932
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
Łukasz Chruściel
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
Ayan Halder
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
Aftab Hussain
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
Deuglo Infosystem Pvt Ltd
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
Google
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 

Recently uploaded (20)

Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Quarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden ExtensionsQuarkus Hidden and Forbidden Extensions
Quarkus Hidden and Forbidden Extensions
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Fundamentals of Programming and Language Processors
Fundamentals of Programming and Language ProcessorsFundamentals of Programming and Language Processors
Fundamentals of Programming and Language Processors
 
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket ManagementUtilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
Utilocate provides Smarter, Better, Faster, Safer Locate Ticket Management
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)APIs for Browser Automation (MoT Meetup 2024)
APIs for Browser Automation (MoT Meetup 2024)
 
May Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdfMay Marketo Masterclass, London MUG May 22 2024.pdf
May Marketo Masterclass, London MUG May 22 2024.pdf
 
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
Introducing Crescat - Event Management Software for Venues, Festivals and Eve...
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Atelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissancesAtelier - Innover avec l’IA Générative et les graphes de connaissances
Atelier - Innover avec l’IA Générative et les graphes de connaissances
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
 
OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024OpenMetadata Community Meeting - 5th June 2024
OpenMetadata Community Meeting - 5th June 2024
 
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf2024 eCommerceDays Toulouse - Sylius 2.0.pdf
2024 eCommerceDays Toulouse - Sylius 2.0.pdf
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 
Using Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional SafetyUsing Xen Hypervisor for Functional Safety
Using Xen Hypervisor for Functional Safety
 
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of CodeA Study of Variable-Role-based Feature Enrichment in Neural Models of Code
A Study of Variable-Role-based Feature Enrichment in Neural Models of Code
 
Empowering Growth with Best Software Development Company in Noida - Deuglo
Empowering Growth with Best Software  Development Company in Noida - DeugloEmpowering Growth with Best Software  Development Company in Noida - Deuglo
Empowering Growth with Best Software Development Company in Noida - Deuglo
 
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI AppAI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
AI Fusion Buddy Review: Brand New, Groundbreaking Gemini-Powered AI App
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 

Final tagless vs free monad

  • 1. Final Tagless vs Free Monad FPure, Kazan, 2019 1 Alexander Granin graninas@gmail.com Twitter: @graninas
  • 2. Plan ● About me ● A Mysterious Software Design ● Final Tagless vs Free Monad ● To Whom It May Concern ● Links 2
  • 3. About me Developer Haskell, C++, C#, Python Worked for Kaspersky Lab, 2GIS, Juspay, Restaumatic, Enecuum Researcher Functional Programming in C++ Writer Book “Functional Design and Architecture” Conferences FPConf, C++ Russia, C++ Siberia, Dev2Dev Meetups LambdaNsk, FProgSpb, DevDay, TechTalks, ... 3
  • 5. cartesianclosedcomicro-che.info/ccc/28 Why academia vs engineering battles are rarely interesting People familiar with theory Haskellers Painstream developers 5
  • 6. cartesianclosedcomicro-che.info/ccc/28 Why academia vs engineering battles are rarely interesting People familiar with theory Haskellers Painstream developers People working on real problems Software engineers Mathskellers Why engineering vs academia battles are rarely useful 6
  • 8. Inversion of Control Why? Complexity reducing Abstraction Separation of concerns Low coupling Effects control Testability Maintainability How? When? 8
  • 9. Inversion of Control Why? Complexity reducing Abstraction Separation of concerns Low coupling Effects control Testability Maintainability How? Final Tagless Free Monad Service Handle Pattern ReaderT Pattern ... When? 9
  • 10. Inversion of Control Why? Complexity reducing Abstraction Separation of concerns Low coupling Effects control Testability Maintainability How? Final Tagless Free Monad Service Handle Pattern ReaderT Pattern ... When? Big applications Complex domain Long lifecycle Team development Sirius Business™ 10
  • 12. data Meteor = Meteor { _size :: Int , _mass :: Int } App State 12
  • 13. data Meteor = Meteor { _size :: Int , _mass :: Int } data Region = NorthEast | NorthWest | SouthEast | SouthWest App State 13
  • 14. data Meteor = Meteor { _size :: Int , _mass :: Int } data Region = NorthEast | NorthWest | SouthEast | SouthWest type Meteors = StateVar (Set Meteor) type Catalogue = Map Region Meteors App State 14
  • 15. data Meteor = Meteor { _size :: Int , _mass :: Int } data Region = NorthEast | NorthWest | SouthEast | SouthWest type Meteors = StateVar (Set Meteor) type Catalogue = Map Region Meteors data AppState = AppState { _catalogue :: Catalogue , _totalMeteors :: StateVar Int , _channel :: StateVar (Set Meteor) } App State 15
  • 16. initState :: StateL AppState initState = do StateL App State 16
  • 17. initState :: StateL AppState initState = do ne <- newVarIO Set.empty nw <- newVarIO Set.empty se <- newVarIO Set.empty sw <- newVarIO Set.empty let catalogue = Map.fromList [ (NorthEast, ne) , (NorthWest, nw) , (SouthEast, se) , (SouthWest, sw) ] StateL App State 17
  • 18. initState :: StateL AppState initState = do ne <- newVarIO Set.empty nw <- newVarIO Set.empty se <- newVarIO Set.empty sw <- newVarIO Set.empty let catalogue = Map.fromList [ (NorthEast, ne) , (NorthWest, nw) , (SouthEast, se) , (SouthWest, sw) ] published <- newVarIO Set.empty total <- newVarIO 0 pure $ AppState catalogue total published StateL App State 18
  • 19. getRandomMeteor :: Region -> RandomL Meteor getRandomMeteor region = do size <- getRandomInt (1, 100) mass <- getRandomInt (size, size * 100) pure $ Meteor size mass region RandomLStateL App State 19
  • 20. getRandomMeteor :: Region -> RandomL Meteor getRandomMeteor region = do size <- getRandomInt (1, 100) mass <- getRandomInt (size, size * 100) pure $ Meteor size mass region publishMeteor :: AppState -> Meteor -> StateL () publishMeteor st meteor = modifyVar (_channel st) $ Set.insert meteor RandomLStateL App State Business Logic 20
  • 21. getRandomMeteor :: Region -> RandomL Meteor getRandomMeteor region = do size <- getRandomInt (1, 100) mass <- getRandomInt (size, size * 100) pure $ Meteor size mass region publishMeteor :: AppState -> Meteor -> StateL () publishMeteor st meteor = modifyVar (_channel st) $ Set.insert meteor meteorShower :: AppState -> Region -> LangL () meteorShower st region = do meteor <- evalRandom $ getRandomMeteor region atomically $ publishMeteor st meteor logInfo $ "New meteor discovered: " <> show meteor LoggerL LangL RandomLStateL App State Business Logic 21
  • 22. meteorsMonitoring :: AppL () meteorsMonitoring = do st <- atomically $ initState LoggerL LangL RandomLStateL AppL App State Business Logic 22
  • 23. meteorsMonitoring :: AppL () meteorsMonitoring = do st <- atomically $ initState process $ forever $ meteorShower st NorthEast process $ forever $ meteorShower st NorthWest process $ forever $ meteorShower st SouthEast process $ forever $ meteorShower st SouthWest process $ forever $ meteorCounter st LoggerL LangL RandomLStateL ProcessL AppL App State Business Logic 23
  • 24. meteorsMonitoring :: AppConfig -> AppL () meteorsMonitoring cfg = do st <- atomically $ initState cfg process $ forever $ meteorShower st NorthEast process $ forever $ meteorShower st NorthWest process $ forever $ meteorShower st SouthEast process $ forever $ meteorShower st SouthWest process $ forever $ meteorCounter st LoggerL LangL RandomLStateL ProcessL AppL App State Business Logic App Configs Application 24
  • 25. meteorsMonitoring :: AppConfig -> AppL () meteorsMonitoring cfg = do st <- atomically $ initState cfg process $ forever $ meteorShower st NorthEast process $ forever $ meteorShower st NorthWest process $ forever $ meteorShower st SouthEast process $ forever $ meteorShower st SouthWest process $ forever $ meteorCounter st main :: IO () main = do loggerRt <- createLoggerRuntime loggerCfg appRt <- createAppRuntime loggerRt startApp appRt $ meteorsMonitoring appCfg LoggerL LangL RandomLStateL ProcessL AppL Runtime, Interpreters, Configs, Environment Application App State Business Logic App Configs 25
  • 26. Implementation Effects, Subsystems & Services (abstracted as Free eDSLs) Domain & Business Logic LoggerL LangL RandomLStateL ProcessL AppL Runtime, Interpreters, Configs, Environment Application App State Business Logic App Configs 26
  • 27. The Only Thing That Matters LoggerL LangL RandomLStateL ProcessL AppL Runtime, Interpreters, Configs, Environment Application App State Business Logic App Configs 27
  • 28. Free Monad vs Final Tagless 28
  • 29. Free Monad vs Final Tagless Language definition 29
  • 30. data LoggerF next where LogMessage :: LogLevel -> Message -> (() -> next) -> LoggerF next makeFunctorInstance ''LoggerF type LoggerL = F LoggerF class Monad m => LoggerL m where logMessage :: LogLevel -> Message -> m () 30
  • 31. data LoggerF next where LogMessage :: LogLevel -> Message -> (() -> next) -> LoggerF next makeFunctorInstance ''LoggerF type LoggerL = F LoggerF data RandomF next where GetRandomInt :: (Int, Int) -> (Int -> next) -> RandomF next makeFunctorInstance ''RandomF type RandomL = F RandomF class Monad m => LoggerL m where logMessage :: LogLevel -> Message -> m () class Monad m => RandomL m where getRandomInt :: (Int, Int) -> m Int 31
  • 32. data LoggerF next where LogMessage :: LogLevel -> Message -> (() -> next) -> LoggerF next makeFunctorInstance ''LoggerF type LoggerL = F LoggerF data RandomF next where GetRandomInt :: (Int, Int) -> (Int -> next) -> RandomF next makeFunctorInstance ''RandomF type RandomL = F RandomF data LangF next where EvalLogger :: LoggerL () -> (() -> next) -> LangF next EvalRandom :: RandomL a -> (a -> next) -> LangF next makeFunctorInstance ''LangF type LangL = F LangF class Monad m => LoggerL m where logMessage :: LogLevel -> Message -> m () class Monad m => RandomL m where getRandomInt :: (Int, Int) -> m Int -- <NOT NEEDED> -- 32
  • 33. data LoggerF next where LogMessage :: LogLevel -> Message -> (() -> next) -> LoggerF next makeFunctorInstance ''LoggerF type LoggerL = F LoggerF data RandomF next where GetRandomInt :: (Int, Int) -> (Int -> next) -> RandomF next makeFunctorInstance ''RandomF type RandomL = F RandomF data LangF next where EvalLogger :: LoggerL () -> (() -> next) -> LangF next EvalRandom :: RandomL a -> (a -> next) -> LangF next makeFunctorInstance ''LangF type LangL = F LangF class Monad m => LoggerL m where logMessage :: LogLevel -> Message -> m () class Monad m => RandomL m where getRandomInt :: (Int, Int) -> m Int -- <NOT NEEDED> -- Boilerplate??! 33
  • 34. data LoggerF next where LogMessage :: LogLevel -> Message -> (() -> next) -> LoggerF next makeFunctorInstance ''LoggerF type LoggerL = F LoggerF data RandomF next where GetRandomInt :: (Int, Int) -> (Int -> next) -> RandomF next makeFunctorInstance ''RandomF type RandomL = F RandomF data LangF next where EvalLogger :: LoggerL () -> (() -> next) -> LangF next EvalRandom :: RandomL a -> (a -> next) -> LangF next makeFunctorInstance ''LangF type LangL = F LangF class Monad m => LoggerL m where logMessage :: LogLevel -> Message -> m () class Monad m => RandomL m where getRandomInt :: (Int, Int) -> m Int -- <NOT NEEDED> -- Functors don’t compose?!! Boilerplate??! 34
  • 35. data LoggerF next where LogMessage :: LogLevel -> Message -> (() -> next) -> LoggerF next makeFunctorInstance ''LoggerF type LoggerL = F LoggerF data RandomF next where GetRandomInt :: (Int, Int) -> (Int -> next) -> RandomF next makeFunctorInstance ''RandomF type RandomL = F RandomF data LangF next where EvalLogger :: LoggerL () -> (() -> next) -> LangF next EvalRandom :: RandomL a -> (a -> next) -> LangF next makeFunctorInstance ''LangF type LangL = F LangF class Monad m => LoggerL m where logMessage :: LogLevel -> Message -> m () class Monad m => RandomL m where getRandomInt :: (Int, Int) -> m Int -- <NOT NEEDED> -- Functors don’t compose?!! Boilerplate??! Too complicated!?? 35
  • 36. The Only Thing That Matters LoggerL LangL RandomLStateL ProcessL AppL Runtime, Interpreters, Configs, Environment Application App State Business Logic App Configs 36
  • 37. 37
  • 38. Free Monad vs Final Tagless Interpreters definition 38
  • 39. interpretRandomF :: RandomF a -> IO a interpretRandomF (GetRandomInt r n) = ... runRandomL :: RandomL a -> IO a runRandomL = foldF interpretRandomF instance RandomL (ReaderT CoreRuntime m) where getRandomInt range = liftIO $ randomRIO range 39
  • 40. interpretRandomF :: RandomF a -> IO a interpretRandomF (GetRandomInt r n) = ... runRandomL :: RandomL a -> IO a runRandomL = foldF interpretRandomF interpretLoggerF :: HsLoggerHandle -> LoggerF a -> IO a interpretLoggerF _ (LogMessage lvl msg n) = ... runLoggerL :: HsLoggerHandle -> L.LoggerL () -> IO () runLoggerL h = foldF (interpretLoggerF h) instance RandomL (ReaderT CoreRuntime m) where getRandomInt range = liftIO $ randomRIO range instance LoggerL (ReaderT CoreRuntime m) where logMessage lvl msg = blaBla 40
  • 41. interpretRandomF :: RandomF a -> IO a interpretRandomF (GetRandomInt r n) = ... runRandomL :: RandomL a -> IO a runRandomL = foldF interpretRandomF interpretLoggerF :: HsLoggerHandle -> LoggerF a -> IO a interpretLoggerF _ (LogMessage lvl msg n) = ... runLoggerL :: HsLoggerHandle -> L.LoggerL () -> IO () runLoggerL h = foldF (interpretLoggerF h) interpretLangF :: CoreRuntime -> LangF a -> IO a interpretLangF coreRt (EvalLogger l n) = ... interpretLangF coreRt (EvalRandom r n) = ... runLangL :: CoreRuntime -> LangL a -> IO a runLangL coreRt = foldF (interpretLangF coreRt) instance RandomL (ReaderT CoreRuntime m) where getRandomInt range = liftIO $ randomRIO range instance LoggerL (ReaderT CoreRuntime m) where logMessage lvl msg = blaBla -- <NOT NEEDED> -- 41
  • 42. interpretRandomF :: RandomF a -> IO a interpretRandomF (GetRandomInt r n) = ... runRandomL :: RandomL a -> IO a runRandomL = foldF interpretRandomF interpretLoggerF :: HsLoggerHandle -> LoggerF a -> IO a interpretLoggerF _ (LogMessage lvl msg n) = ... runLoggerL :: HsLoggerHandle -> L.LoggerL () -> IO () runLoggerL h = foldF (interpretLoggerF h) interpretLangF :: CoreRuntime -> LangF a -> IO a interpretLangF coreRt (EvalLogger l n) = ... interpretLangF coreRt (EvalRandom r n) = ... runLangL :: CoreRuntime -> LangL a -> IO a runLangL coreRt = foldF (interpretLangF coreRt) instance RandomL (ReaderT CoreRuntime m) where getRandomInt range = liftIO $ randomRIO range instance LoggerL (ReaderT CoreRuntime m) where logMessage lvl msg = blaBla -- <NOT NEEDED> -- Boilerplate??! 42
  • 43. interpretRandomF :: RandomF a -> IO a interpretRandomF (GetRandomInt r n) = ... runRandomL :: RandomL a -> IO a runRandomL = foldF interpretRandomF interpretLoggerF :: HsLoggerHandle -> LoggerF a -> IO a interpretLoggerF _ (LogMessage lvl msg n) = ... runLoggerL :: HsLoggerHandle -> L.LoggerL () -> IO () runLoggerL h = foldF (interpretLoggerF h) interpretLangF :: CoreRuntime -> LangF a -> IO a interpretLangF coreRt (EvalLogger l n) = ... interpretLangF coreRt (EvalRandom r n) = ... runLangL :: CoreRuntime -> LangL a -> IO a runLangL coreRt = foldF (interpretLangF coreRt) instance RandomL (ReaderT CoreRuntime m) where getRandomInt range = liftIO $ randomRIO range instance LoggerL (ReaderT CoreRuntime m) where logMessage lvl msg = blaBla -- <NOT NEEDED> -- Boilerplate??! Interpreters don’t compose?!! 43
  • 44. interpretRandomF :: RandomF a -> IO a interpretRandomF (GetRandomInt r n) = ... runRandomL :: RandomL a -> IO a runRandomL = foldF interpretRandomF interpretLoggerF :: HsLoggerHandle -> LoggerF a -> IO a interpretLoggerF _ (LogMessage lvl msg n) = ... runLoggerL :: HsLoggerHandle -> L.LoggerL () -> IO () runLoggerL h = foldF (interpretLoggerF h) interpretLangF :: CoreRuntime -> LangF a -> IO a interpretLangF coreRt (EvalLogger l n) = ... interpretLangF coreRt (EvalRandom r n) = ... runLangL :: CoreRuntime -> LangL a -> IO a runLangL coreRt = foldF (interpretLangF coreRt) instance RandomL (ReaderT CoreRuntime m) where getRandomInt range = liftIO $ randomRIO range instance LoggerL (ReaderT CoreRuntime m) where logMessage lvl msg = blaBla -- <NOT NEEDED> -- Boilerplate??! Interpreters don’t compose?!! Slow??!! 44
  • 45. 45
  • 46. 46
  • 47. 47
  • 48. Church Encoded Free faster than Final Tagless. 48
  • 49. FT FreeM ChurchM 10 0.155 0.155 0.167 100 0.16 0.16 0.16 1000 0.161 0.176 0.15 10000 0.166 1.448 0.17 100000 0.31 ∞ 0.276 1000000 1.618 ∞ 1.464 10000000 14.781 ∞ 14.528 20000000 35.751 ∞ 29.888 30000000 53.655 ∞ 46.489 FT FreeM ChurchM 10 0.165 0.168 0.162 100 0.166 0.17 0.165 1000 0.17 0.161 0.163 10000 0.174 0.757 0.18 100000 0.258 ∞ 0.307 1000000 1.357 ∞ 1.236 10000000 11.459 ∞ hang Use logs, log total Use delays, factor = 0 Use logs, log total No delays 49
  • 50. Free Monad vs Final Tagless Business Logic 50
  • 51. getRandomMeteor :: Region -> RandomL Meteor getRandomMeteor :: RandomL m => Region -> m Meteor 51
  • 52. getRandomMeteor :: Region -> RandomL Meteor publishMeteor :: AppState -> Meteor -> StateL () getRandomMeteor :: RandomL m => Region -> m Meteor publishMeteor :: AppState -> Meteor -> STM () 52
  • 53. getRandomMeteor :: Region -> RandomL Meteor publishMeteor :: AppState -> Meteor -> StateL () meteorShower :: AppState -> Region -> LangL () getRandomMeteor :: RandomL m => Region -> m Meteor publishMeteor :: AppState -> Meteor -> STM () meteorShower :: (MonadUnliftIO m, LoggerL m, RandomL m) => AppState -> Region -> m () 53
  • 54. getRandomMeteor :: Region -> RandomL Meteor publishMeteor :: AppState -> Meteor -> StateL () meteorShower :: AppState -> Region -> LangL () meteorsMonitoring :: AppConfig -> AppL () getRandomMeteor :: RandomL m => Region -> m Meteor publishMeteor :: AppState -> Meteor -> STM () meteorShower :: (MonadUnliftIO m, LoggerL m, RandomL m) => AppState -> Region -> m () meteorsMonitoring :: (MonadUnliftIO m, ControlFlowL m, LoggerL m, RandomL m) => AppConfig -> m () 54
  • 55. getRandomMeteor :: RandomL m => Region -> m Meteor publishMeteor :: AppState -> Meteor -> STM () meteorShower :: (MonadUnliftIO m, LoggerL m, RandomL m) => AppState -> Region -> m () meteorsMonitoring :: (MonadUnliftIO m, ControlFlowL m, LoggerL m, RandomL m) => AppConfig -> m () 55 Boilerplate.
  • 56. getRandomMeteor :: RandomL m => Region -> m Meteor publishMeteor :: AppState -> Meteor -> STM () meteorShower :: (MonadUnliftIO m, LoggerL m, RandomL m) => AppState -> Region -> m () meteorsMonitoring :: (MonadUnliftIO m, ControlFlowL m, LoggerL m, RandomL m) => AppConfig -> m () Boilerplate. Maintenance nightmare. 56
  • 57. getRandomMeteor :: RandomL m => Region -> m Meteor publishMeteor :: AppState -> Meteor -> STM () meteorShower :: (MonadUnliftIO m, LoggerL m, RandomL m, HasCoreRuntime m) => AppState -> Region -> m () meteorsMonitoring :: (MonadUnliftIO m, ControlFlowL m, LoggerL m, RandomL m, HasCoreRuntime m) => AppConfig -> m () Maintenance nightmare. Boilerplate. Implementation details. 57
  • 58. getRandomMeteor :: (MonadUnliftIO m, RandomL m) => Region -> m Meteor publishMeteor :: AppState -> Meteor -> STM () meteorShower :: (MonadUnliftIO m, LoggerL m, RandomL m, HasCoreRuntime m) => AppState -> Region -> m () meteorsMonitoring :: (MonadUnliftIO m, ControlFlowL m, LoggerL m, RandomL m, HasCoreRuntime m) => AppConfig -> m () Maintenance nightmare. Boilerplate. Illusion of control. Implementation details. 58
  • 59. getRandomMeteor :: Region -> AppEff Meteor publishMeteor :: AppState -> Meteor -> STM () meteorShower :: AppState -> Region -> AppEff () meteorsMonitoring :: AppConfig -> AppEff () type Eff = ( MonadUnliftIO m , ControlFlowL m , LoggerL m , RandomL m ) newtype AppEff a = AppT { unAppT :: ReaderT CoreRuntime Eff a } deriving (Functor, Applicative, Monad) 59
  • 60. LoggerL RandomL MonadUnliftIO ControlFlowL STMDatabaseL UnpredictedRandomEffect LaunchRockets LoggerL LangL RandomLStateL ProcessL AppL Runtime, Interpreters, Configs, Environment Application App State Business Logic App Configs Runtime DatabaseL IOL Business Logic App State App Configs 60
  • 61. 61 Effect system != Layering.
  • 62. 62 Effect system != Layering. Effect systems is an exceptionally bad idea which could only have originated in academia.
  • 63. To Whom It May Concern 63
  • 64. Functors of free monads aren’t composable. 64
  • 65. Functors of free monads aren’t composable. Interpreters of free monads aren’t composable. 65
  • 66. Functors of free monads aren’t composable. Interpreters of free monads aren’t composable. Free monads aren’t composable. 66
  • 67. Functors of free monads aren’t composable. Interpreters of free monads aren’t composable. Free monads aren’t composable. Free monads are slow. 67
  • 68. Functors of free monads aren’t composable. Interpreters of free monads aren’t composable. Free monads aren’t composable. Free monads are slow. Essentially, Free Monads are equivalent to Final Tagles. 68
  • 69. Functors of free monads aren’t composable. Interpreters of free monads aren’t composable. Free monads aren’t composable. Free monads are slow. Essentially, Free Monads are equivalent to Final Tagles. This paper says it’s impossible. 69
  • 70. Functors of free monads aren’t composable. Interpreters of free monads aren’t composable. Free monads aren’t composable. Free monads are slow. Essentially, Free Monads are equivalent to Final Tagles. This paper says it’s impossible. This paper says it’s bad. 70
  • 71. Functors of free monads aren’t composable. Interpreters of free monads aren’t composable. Free monads aren’t composable. Free monads are slow. Essentially, Free Monads are equivalent to Final Tagles. This paper says it’s impossible. This paper says it’s bad. You haven’t read the X’s paper, how dare you?! 71
  • 72. Software development is not “Math”. Software development is “Physics”. In here, experiment is the only measure of truth. 72
  • 73. Links Code Hydra framework My book Functional Design and Architecture Book’s Patreon Patreon/functional_design_and_architecture My other talks https://graninas.com/talks-eng My poetry ;) https://graninas.com/creations/#poetry 73
  • 74. Free monads are powerful and fast. FPure, Kazan, 2019 74 Alexander Granin graninas@gmail.com Twitter: @graninas