Functional programming with monads combined with comonads · 2010-06-07 · Functional programming...
Transcript of Functional programming with monads combined with comonads · 2010-06-07 · Functional programming...
![Page 1: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/1.jpg)
Functional programming with monads combined
with comonads
Dominic OrchardWednesday 2nd June, 2010
ICFP PC Functional Programming Workshop, MSR, Cambridge
![Page 2: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/2.jpg)
Some functions...division with possible divide-by-zero exception
div : (R, R)! (R + 1)
print a character to stdout
putChar : Char! IO ()
set user state in parser
putState : u! ParsecT s u m ()
Spot the similarity? f : a! T b
![Page 3: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/3.jpg)
Monads
coproduct (sum) monad (or Maybe) (_ + 1)div : (R, R)! (R + 1)
IO (state) monad
putChar : Char! IO ()
T is a monad structure
![Page 4: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/4.jpg)
Monads
µ : T (T a)! T a! : a! T a
Operations of monad
• Framework for working with morphisms like:
Kleisli category of a T monad
f : a! T b
called Kleisli morphisms
![Page 5: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/5.jpg)
!=
Monads
f : a! T b
g : b! T c
Given two Kleisli morphisms
![Page 6: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/6.jpg)
Monads( )! : (a! T b)! (T a! T b)Extension
Lets us compose Kleisli morphisms
f : a! T b
g! : T b! T c
=
g! ! f : a " T c
( )! = µ ! (Tf)
![Page 7: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/7.jpg)
Practical Programming with Monads
• Can use compose and/or extension point free e.g.
echo = (putChar <.> (const getChar)) ()
• What if we want to reuse an intermediate result?
echo’ = ((\x -> ((\_ -> putChar x)<.> (\_ -> putChar x)) ())<.> (const getChar)) ()
![Page 8: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/8.jpg)
Practical Programming with Monads
• do notation improves programming with Kleisli morphisms with binding of intermediate results
echo = do x <- getCharputChar xputChar x
![Page 9: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/9.jpg)
Practical Programming with Monads
• extension happens through <-
• binder “y” is parameter to Kleisli morphism
do y <- e1 ! extend (\y -> e2) e1e2
![Page 10: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/10.jpg)
Some more functions...
next : Stream a! a
next item in a stream (head of tail)
staged computation evaleval : ! a! a
loop body “kernel” function on an array
kernel : (Array a! i)" a
Spot the similarity? f : D a! b
![Page 11: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/11.jpg)
Comonads
Operations of comonad (dual of a monad)
! : D a! D (D a)! : D a! a
µ : T (T a)! T a! : a! T a
cf. operations of monad
is a comonad structureD
![Page 12: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/12.jpg)
Example comonad: Array
Array is an array with a cursor
![Page 13: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/13.jpg)
Example comonad: Array
! : Array a! a
fmap : (a! b)! Array a! Array b
![Page 14: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/14.jpg)
Example comonad: Array
! : Array a! Array(Array a)
![Page 15: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/15.jpg)
Comonads
f : D a! b• Framework for working with morphisms like:
coKleisli category of a D comonad
cf. Kleisli morphisms:
f : a! T b
called coKleisli morphisms
![Page 16: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/16.jpg)
Comonads
f : D a! bg : D b! c g ! f† : D a " c
( )! : (a! T b)! (T a! T b)
cf. Kleisli extension
Coextension for CoKleisli composition:
f† : D a! D b
( )† : (D a! b)! (D a! D b)
Extension (coextension)
( )† = (D f) ! !
![Page 17: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/17.jpg)
Example comonad: Array
( )† : (Array a! b)! (Array a! Array b)
Array a! b
![Page 18: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/18.jpg)
Dr. Jekyll & Mr. Hyde
div : (R, R)! (R + 1)Recall:
Consider:
div’ = div (x, y)
div’ : ArrayR! (R+1)
![Page 19: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/19.jpg)
Coextension of div’
div’ : ArrayR! (R+1)
(div’)† : ArrayR! Array (R+1)
( )† : (D a! b)! (D a! D b)Coextension on div’:
Want to “pull-out” any divide-by-zero exceptions
![Page 20: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/20.jpg)
throwExceptions : Array (R+1)! ((ArrayR)+1)
Instance of a distributive law of D over T
! : D T a! T D a
![Page 21: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/21.jpg)
BiKleisli Category
BiKleisli category of a T monad and a D comonad
• Framework for working with morphisms like:
called BiKleisli morphisms
f : D a! T b
![Page 22: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/22.jpg)
BiKleisli CategoryComposition:
! : DT a! TD bwhere
g ! f = (extend g) ! ! ! (coextend f)! : (D b " T c) " (D a " T b) " (D a " T c)
(extend g)! ! (coextend f) : D a " T c
(extend g) : T (D b)! T c
(coextend f) : D a! D(T b)! ! (coextend f) : D a " T (D b)
[Harmer, Hyland, et al. ’07,Uustalu & Vene ’05, Power & Watanabe ’02, Brookes & Stone ’93]
Type check:
![Page 23: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/23.jpg)
But is just BiKleisli composition enough?
f : ArrayR! (R+1) g : ArrayR! (R+1)
g ! f : ArrayR " (R+1)
A comonadic result, not just a single monadic valueWe want:
![Page 24: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/24.jpg)
Biextend
• Derived from a coKleisli category on a Kleisli category
• Perform extension operations through both layers of category, using lambda to get consistent types
( )! : (D a! T b)! T (D a)! T (D b)f ! = extend (! ! coextend f)
![Page 25: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/25.jpg)
Biextend( )! : (D a! T b)! T (D a)! T (D b)
div’ : ArrayR! (R+1)(div!)! : ((ArrayR) +1)! ((ArrayR) +1)
E.g. biextend on div’:
![Page 26: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/26.jpg)
Biextend( )! : (D a! T b)! T (D a)! T (D b)
Can derive composition from biextend
g! ! f ! : T (D a) " T (D c)
T ! : T (D c)! T c
!D : D a! T (D a)
g ! f = (T !) ! (biextend g) ! (biextend f) ! "D
![Page 27: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/27.jpg)
Biextend’
• Not shown further today
• Idea: structure purely local effects, whereas biextend for effects that become global
biextend : (D a! T b)! T (D a)! T (D b)
biextend! : (D a ! T b) ! D(T a) ! D (T b)biextend! f = coextend ((extend f) " !)
![Page 28: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/28.jpg)
Example: effectful arrays
• Mutable arrays in Haskell
readArray :: (Ix i)! IOArray i e" i" IO e
writeArray :: (Ix i)! IOArray i e" i" e" IO ()
• Look like biKleisli morphisms
• Semantics of effects and arrays conflated
![Page 29: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/29.jpg)
Example: effectful arrays
• Decouple pure, array semantics from state semantics with Array and State
• Effectful array computations as BiKleislis:
Array a! State b
![Page 30: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/30.jpg)
Example: effectful arrays
• Define just lambda! : Array (State a)! State (Array a)
instance Dist Array State wheredist (Array (b1, b2) arr c) =
letres = mapM (\c’ -> counit (Array (b1, b2) arr c’)) [b1..b2]
inextend (\vals ->unit (Array (buildArray [b1..b2] vals) c (b1, b2)
) res
![Page 31: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/31.jpg)
Example: effectful arrays• Thus we get biextend:
e.g. laplace :: Array Double -> State Double...lowpass :: Array Double -> State Double...
x’ :: State (Array Double)x’ = biextend (laplace <.> lowpass) x
biextend : (Array a! State b)!State (Array a)! State (Array b)
![Page 32: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/32.jpg)
Example: effectful arrays• For real IOArray’s cannot define:
! : Array (State a)! State (Array a)
• Memory consistency!
• For IOUArray’s also for memory consistency AND element restrictions reasons
• But we can define (a restricted) biextend
biextend :(Array a! State a)!State (Array a)! State (Array a)
![Page 33: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/33.jpg)
Practical programming with monads & comonads?
• Can use point-free style here, e.g. for effectful arrays:
x’ = biextend (laplace <.> lowpass) x
• do notation for monads/Kleisli
• let-binding for comonads/coKleisli
![Page 34: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/34.jpg)
Practical programming with monads & comonads?
• What if we want to reuse bound intermediate results?
• Recall biextend:
• Solution: use do with a “half”-biextend
( )! : (D a! T b)! T (D a)! T (D b)f ! = extend (! ! coextend f)
( )!† : (D a ! T b) ! (D a ! T (D b)
f!† = ! " coextend f
![Page 35: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/35.jpg)
Practical programming with monads & comonads?
• “Half”-biextend (operator >>==):
• do notation completes biextend by applying extend over (>>==) in the desugaring of do
( )!† : (D a ! T b) ! (D a ! T (D b)
f!† = ! " coextend f
do y <- e1 ! extend (\y -> f >>== y) e1f >>== y
! extend (\y -> (lambda . coextend f) y) e1
![Page 36: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/36.jpg)
Practical programming with monads & comonads?
• E.g.
x’’ = do elems <- newListArray (0,9)([1,5,2,3,4,0,13,8,5,7]::[Double])
x0 <- return $ Array elemsprintArray x0x1 <- lowpass >>== x0printArray x1x2 <- laplace >>== x1printArray x2x3 <- convolve >>== x2printArray x3
![Page 37: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/37.jpg)
Conclusions
• Biextend
• Good for programming with BiKleislis
• Allows computation on intermediate values
• Side-step real world restrictions on abstract nonsense
![Page 38: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/38.jpg)
Further Work
• With monads, programming with extend is often easier than programming with
• Extend produces
• Axiomatisation for biextend that produces ?
• Another expressive -equivalent idiom?
µ
!!
µ
![Page 39: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/39.jpg)
Further Work
• Experiment with biextend’ further.
• Dual distributive law?
biextend! : (D a! T b)! D(T a)! D (T b)
biextend : (D a! T b)! T (D a)! T (D b)
! : DT ! TD
!! : TD ! DT
![Page 40: Functional programming with monads combined with comonads · 2010-06-07 · Functional programming with monads combined with comonads Dominic Orchard Wednesday 2nd June, 2010 ICFP](https://reader030.fdocuments.net/reader030/viewer/2022041111/5f13c6637afb7972b645e3e3/html5/thumbnails/40.jpg)
Thank you.