Slide 1

Slide 1 text

Phil Freeman COMONADIC! The e Is coday.today

Slide 2

Slide 2 text

Hello ● Hello, I’m Phil ● I write Haskell and PureScript at Lumi ● I like building user interface libraries in PureScript: ○ React-Basic ○ Thermite ○ SDOM ○ Behaviors ○ Purview ○ React-Explore ● I also like to study category theory

Slide 3

Slide 3 text

Agenda ● An intuition for comonads ● How can we specify user interfaces? ● How can we talk about specifying user interfaces? ● Some other interesting ideas

Slide 4

Slide 4 text

Monads Mon Image: NASA

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

Monads class Functor m ⇒ Monad m where return ∷ a → m a join ∷ m (m a) → m a (>>=) ∷ m a → (a → m b) → m b (>=>) :: Monad m ⇒ (a → m b) → (b → m c) → a → m c (f >=> g) a = f a >>= g f >=> return = f return >=> f = f f >=> (g >=> h) = (f >=> g) >=> h

Slide 7

Slide 7 text

Comonads class Functor w ⇒ Comonad w where extract ∷ w a → a duplicate ∷ w a → w (w a) (=>>) ∷ w a → (w a → b) → w b (=>=) :: Comonad m ⇒ (w a → b) → (w b → c) → w a → c (f =>= g) w = g (w =>> f) f =>= extract = f extract =>= f = f f =>= (g =>= h) = (f =>= g) =>= h

Slide 8

Slide 8 text

Examples?

Slide 9

Slide 9 text

The Store Comonad data Store s a = Store s (s → a) instance Comonad (Store s) where extract (Store here go) = go here duplicate (Store here go) = Store here $ \there → Store there go

Slide 10

Slide 10 text

The Traced Comonad data Traced w a = Traced (w → a) instance Monoid w ⇒ Comonad (Traced w) where extract (Traced f) = f mempty duplicate (Traced f) = Traced $ \w → Traced (f . (w ◇))

Slide 11

Slide 11 text

Intuition?

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

More Reading ● Cofree meets Free http://blog.sigfpe.com/2014/05/cofree-meets-free.html ● Comonads in Everyday Life https://fmapfixreturn.wordpress.com/2008/07/09/comonads-in-everyday-life/

Slide 14

Slide 14 text

Declarative UIs Trends in UIs: ● No more direct manipulation ● One-way data flow ● Describe what the UI state should be, not how to reach it.

Slide 15

Slide 15 text

Virtual DOM The virtual DOM API in 4 lines: data VDOM e data Patch diff ∷ VDOM e → VDOM e → Patch apply ∷ Patch → IO Unit (e f Eve s )

Slide 16

Slide 16 text

Components We can build components: data Component model = Component { initialState ∷ model , render ∷ model → VDOM model }

Slide 17

Slide 17 text

E.g. Counter counter ∷ Component Int counter updateState = Component { initialState: 0 , render = \value → button [onClick \_ → value + 1] [text ("Current value = " ⧺ show value)] }

Slide 18

Slide 18 text

A Comonad Appears Hey, that looks like Store! type Component model = Store model (VDOM model) What do the Comonad functions do? extract ∷ Component model → VDOM model duplicate ∷ Component model → Store model Component

Slide 19

Slide 19 text

The Future is Comonadic extract ∷ Component model → VDOM model extract renders the component’s current state duplicate ∷ Component model → Store model (Component model) duplicate captures the possible future states of the component

Slide 20

Slide 20 text

Exploring the Future How can we explore the future? future ∷ Store model (Component model) We need a function explore ∷ Store model Component → Component model Image: xkcd.com

Slide 21

Slide 21 text

Exploring the Future To usefully implement explore ∷ Store model Component → Component model we can ● read the current state ● move to a new state Which can be packaged up using the State monad

Slide 22

Slide 22 text

Exploring the Future explore ∷ State model () → Store model Component → Component model explore state (Store here go) = go there where (_, there) = runState state here

Slide 23

Slide 23 text

Components using State data Component model = Component { initialState ∷ model , render ∷ model → VDOM (State model ()) }

Slide 24

Slide 24 text

Counter using State counter ∷ Component Int counter updateState = Component { initialState: 0 , render = \value → button [onClick \_ → modify (\n → n + 1)] [text ("Current value = " ⧺ show value)] }

Slide 25

Slide 25 text

Let’s Summarize ● A component is described by Store model (VDOM (State model ())) ● We can render a component using extract ● We can observe possible future states of a component using duplicate

Slide 26

Slide 26 text

Let’s Generalize! ● A component is described by w (VDOM (m ())) ● We can render a component using extract ● We can observe possible future states of a component using duplicate (Laz va ed!)

Slide 27

Slide 27 text

Pairings We require the existence of a function explore ∷ m () → w a → a We can use the more general concept of pairing ∷ m (a → b) → w a → b

Slide 28

Slide 28 text

Pairings State s Writer w Reader e Free f Free ((,) i) Store s (React) Traced w (Incremental) Env e Cofree g (*) (Halogen) Cofree ((→) i) (Redux, Elm) * when f pairs with g pairs with

Slide 29

Slide 29 text

Pairings For Free We get a (law-abiding!) monad with a pairing for free: (http://comonad.com/reader/2011/monads-from-comonads/) data Co w a = Co (∀ r. w (a → r) → r) instance Comonad w ⇒ Monad (Co w) explore :: Co w (a → b) → w a → b

Slide 30

Slide 30 text

Let’s Summarize ● A component is described by w (VDOM (Co w ())) ● We can select the next future state using Co w () This is implemented in purescript-react-explore. type Handler w = Co w () type Component w = w (VDOM (Handler w)))

Slide 31

Slide 31 text

So What? ● We’ve unified several common approaches to UIs under one abstraction ● We have control over component state transitions ● We now have a language for studying the approaches themselves ○ E.g. comonad morphisms correspond to interpreters ○ E.g. every comonadic UI can be interpreted using Store (React) ● We can generalize this approach to comonads in other categories ● We can use this intuition to find new comonads

Slide 32

Slide 32 text

Further Reading...

Slide 33

Slide 33 text

Combining Components

Slide 34

Slide 34 text

Day Convolution Day (1970) defines the following convolution product of functors: For example: data Day f g a = forall x. Day (f (x → a)) (g x) Day ((→) w) ((→) w’) a ~ exists x. (w → x → a, w’ → x) ~ w → w’ → a ~ (w, w’) → a

Slide 35

Slide 35 text

Day Convolution Theorem Day f g is a comonad whenever f and g are both comonads. In fact, Day makes the comonad category into a (closed) symmetric monoidal category. TO : fi n u t e y ex n is

Slide 36

Slide 36 text

Day Convolution Day (Store s) w Day (Traced w’) w Day (Env e) w StoreT s w TracedT w’ w EnvT e w ≅

Slide 37

Slide 37 text

Symmetric Monoidal Categories A symmetric monoidal category ( , ⨂, I) is defined by a bifunctor ⨂ : ⨉ → with unit I (*) which is ● Associative (*) ● Symmetric (*) * up to isomorphism

Slide 38

Slide 38 text

Closed Symmetric Monoidal Categories A closed symmetric monoidal category has right adjoints for each tensoring functor A ⨂ - : → A ⇒ - : →

Slide 39

Slide 39 text

Closed Symmetric Monoidal Categories We can use linear lambda calculus, the internal language of closed symmetric monoidal categories to talk about Day convolution and component composition.

Slide 40

Slide 40 text

Day is Closed The internal Hom is given by Notice that: data Hom f g a = Hom (∀ r. f (x → r) -> g r) Hom f Identity a ~ ∀ r. f (x → r) -> r ~ Co f a

Slide 41

Slide 41 text

move ∷ ((f ⇒ 1) ⇒ (g ⇒ 1) ⇒ (f ⨂ g ⇒ 1)) () move = ⟦ linear | \f† g† pair let (f, g) = pair () = f† f in g† g ⟧ Monads Annihilate Comonads To change application state, we need E.g. (f ⇒ 1) ()

Slide 42

Slide 42 text

Comonad Optics We can form optics for comonads just like lenses for types: type Optic s t a b = s ↝ a ⨂ (b ⇒ t) day1 ∷ Optic (a ⨂ c) (b ⨂ c) a b day2 ∷ Optic (c ⨂ a) (c ⨂ a) a b store1 ∷ Optic (StoreT s a) (StoreT s b) a b store2 ∷ Optic (StoreT s a) (StoreT s’ b) (Store s) (Store s’) (Lo k s ik L !)

Slide 43

Slide 43 text

Iterated Day Convolution Day is our internal product type Let’s form an internal record type! See purescript-smash (also an implementation of extensible coeffects) data Smash (r ∷ # (Type -> Type)) a

Slide 44

Slide 44 text

Bits and Pieces ● Comonads are closed under certain equalizers ● There is a Sum construction for modeling UIs with multiple optional states ○ Can also be used to construct UIs for lists

Slide 45

Slide 45 text

Questions?