Updated and corrected.
This commit is contained in:
parent
144c670dd6
commit
032da3c24a
34 changed files with 177 additions and 181 deletions
114
categories.html
114
categories.html
|
@ -126,7 +126,7 @@
|
|||
<img class="right" src="categories/img/mindblown.gif" alt="mind blown"/>
|
||||
<p>Math vocabulary used in this presentation:</p>
|
||||
<blockquote>
|
||||
<p>Category, Morphism, Associativity, Preorder, Functor, Endofunctor, Categorial property, Commutative diagram, Isomorph, Initial, Dual, Monoid, Natural transformation, Monad, κατα-morphism, ...</p>
|
||||
<p>Category, Morphism, Associativity, Preorder, Functor, Endofunctor, Categorial property, Commutative diagram, Isomorph, Initial, Dual, Monoid, Natural transformation, Monad, Klesli arrows, κατα-morphism, ...</p>
|
||||
</blockquote>
|
||||
<img class="right" src="categories/img/readingcat.jpg" alt="lolcat"/>
|
||||
<table style="width:70%">
|
||||
|
@ -192,9 +192,9 @@ LOLCat
|
|||
|
||||
<p> A Category \(\mathcal{C}\) is defined by:</p>
|
||||
<ul>
|
||||
<li> <em>Objects (\(\ob{C}\))</em>,</li>
|
||||
<li> <em>Morphisms (\(\hom{C}\))</em>,</li>
|
||||
<li> a <em>Composition law (∘)</em></li>
|
||||
<li> <em>Objects <span class="yellow">\(\ob{C}\)</span></em>,</li>
|
||||
<li> <em>Morphisms <span class="yellow">\(\hom{C}\)</span></em>,</li>
|
||||
<li> a <em>Composition law <span class="yellow">(∘)</span></em></li>
|
||||
<li> obeying some <em>Properties</em>.</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
@ -497,14 +497,15 @@ A <em>functor</em> <span class="yellow">\(\F\)</span> from <span class="blue">\(
|
|||
</section>
|
||||
<section class="slide">
|
||||
<h2 id="haskell-kinds">Haskell Kinds</h2>
|
||||
<p>In Haskell some types can take type variable. Typically: <code>[a]</code>.</p>
|
||||
<p>In Haskell some types can take type variable(s). Typically: <code>[a]</code>.</p>
|
||||
<pre><code>data Tree a = Node a [Tree a]
|
||||
data CTree a b = CNode a [b]</code></pre>
|
||||
<p>Types have <em>kind</em>; The kind is to type what type is to function. Kind are the "type" for some types (so meta).</p>
|
||||
<p>Types have <em>kind</em>; The kind is to type what type is to function. Kind are the types for types (so meta).</p>
|
||||
<pre><code>Int, Char :: *
|
||||
[], Maybe, Tree :: * -> *
|
||||
CTree :: * -> * -> *
|
||||
[Int], Maybe Char, Tree [Int] :: *</code></pre>
|
||||
[Int], Maybe Char, Tree [Int] :: *
|
||||
CTree [Int] :: * -> *</code></pre>
|
||||
</section>
|
||||
<section class="slide">
|
||||
<h2 id="haskell-types">Haskell Types</h2>
|
||||
|
@ -519,7 +520,7 @@ f :: a -> [a] -- Many choices
|
|||
-- can only rearrange: duplicate/remove/reorder elements
|
||||
-- for example: the type of addOne isn't [a] -> [a]
|
||||
addOne l = map <span class="red">(+1)</span> l
|
||||
-- The (+1) force a to be a Num.</code></pre>
|
||||
-- The (+1) force 'a' to be a Num.</code></pre>
|
||||
|
||||
<p>
|
||||
<p><span class="small base01">★:<a href="http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf">Theorems for free!, Philip Wadler, 1989</a></span></p>
|
||||
|
@ -543,10 +544,10 @@ It must implement <code>fmap :: (a -> b) -> (F a -> F b)</code>.
|
|||
<pre class="haskell"><code>data Maybe a = Just a | Nothing
|
||||
instance Functor Maybe where
|
||||
fmap :: (a -> b) -> (Maybe a -> Maybe b)
|
||||
fmap f (Just a) = f a
|
||||
fmap f (Just a) = Just (f a)
|
||||
fmap f Nothing = Nothing
|
||||
|
||||
fmap (+1) (Just 1) == 2
|
||||
fmap (+1) (Just 1) == Just 2
|
||||
fmap (+1) Nothing == Nothing
|
||||
fmap head (Just [1,2,3]) == Just 1</code></pre>
|
||||
</section>
|
||||
|
@ -630,14 +631,15 @@ Haskell types is fractal:</p>
|
|||
</section>
|
||||
<section class="slide">
|
||||
<h2 id="also-functor-inside-hask">Also Functor inside \(\Hask\)</h2>
|
||||
<p><code>length</code> can be seen as a Functor from the category <code>[a]</code> to the cateogry <code>Int</code>:</p>
|
||||
<ul class="left">
|
||||
<p>\(\mathtt{[a]}∈\ob{\Hask}\)</code> but is also a complete category. The same can be said for <code>Int</code>.</p>
|
||||
<p><code>length</code> is a Functor from the category <code>[a]</code> to the cateogry <code>Int</code>:</p>
|
||||
<ul class="left" style="max-width:40%">
|
||||
<li>\(\ob{\mathtt{[a]}}=\{∙\}\)</li>
|
||||
<li>\(\hom{\mathtt{[a]}}=\mathtt{[a]}\)</li>
|
||||
<li>\(∘=\mathtt{(++)}\)</li>
|
||||
</ul>
|
||||
<p class="left" style="margin:2em 3em">⇒</p>
|
||||
<ul class="left">
|
||||
<ul class="left" style="max-width:40%">
|
||||
<li>\(\ob{\mathtt{Int}}=\{∙\}\)</li>
|
||||
<li>\(\hom{\mathtt{Int}}=\mathtt{Int}\)</li>
|
||||
<li>\(∘=\mathtt{(+)}\)</li>
|
||||
|
@ -673,8 +675,8 @@ toTree :: [a] -> Tree a
|
|||
toTree [] = Empty
|
||||
toTree (x:xs) = Node x [toTree xs]</pre>
|
||||
</code>
|
||||
<p><code>toTree</code> is a natural transformation. It is also a morphism from <code>[]</code> to <code>Tree</code> in the Category of \(\) endofunctors.</p>
|
||||
<img style="float:left;width:50%" src="categories/img/mp/nattrans-list-tree.png" alt="natural transformation commutative diagram"/>
|
||||
<p><code>toTree</code> is a natural transformation. It is also a morphism from <code>[]</code> to <code>Tree</code> in the Category of \(\Hask\) endofunctors.</p>
|
||||
<img style="float:left;width:40%" src="categories/img/mp/nattrans-list-tree.png" alt="natural transformation commutative diagram"/>
|
||||
<figure style="float:right;width:40%">
|
||||
<img src="categories/img/mp/list-tree-endofunctor-morphism.png" alt="natural transformation commutative diagram"/>
|
||||
</figure>
|
||||
|
@ -688,8 +690,8 @@ toList :: Tree a -> [a]
|
|||
toList Empty = []
|
||||
toList (Node x l) = [x] ++ concat (map toList l)</pre>
|
||||
</code>
|
||||
<p><code>toList</code> is a natural transformation. It is also a morphism from <code>Tree</code> to <code>[]</code> in the Category of \(\) endofunctors.</p>
|
||||
<img style="float:left;width:50%" src="categories/img/mp/nattrans-tree-list.png" alt="natural transformation commutative diagram"/>
|
||||
<p><code>toList</code> is a natural transformation. It is also a morphism from <code>Tree</code> to <code>[]</code> in the Category of \(\Hask\) endofunctors.</p>
|
||||
<img style="float:left;width:40%" src="categories/img/mp/nattrans-tree-list.png" alt="natural transformation commutative diagram"/>
|
||||
<figure style="float:right;width:40%">
|
||||
<img src="categories/img/mp/tree-list-endofunctor-morphism.png" alt="natural transformation commutative diagram"/> <figcaption><code>toList . toTree = id</code> <span class="and">&</span><br/> <code>toTree . toList = id</code> <span style="visibility:hidden"><span class="and">&</span></span><br/> therefore <code>[]</code> <span class="and">&</span> <code>Tree</code> are <span class="yellow">isomorph</span>. </figcaption>
|
||||
</figure>
|
||||
|
@ -702,8 +704,8 @@ toList (Node x l) = [x] ++ concat (map toList l)</pre>
|
|||
toMaybe [] = Nothing
|
||||
toMaybe (x:xs) = Just x</pre>
|
||||
</code>
|
||||
<p><code>toMaybe</code> is a natural transformation. It is also a morphism from <code>[]</code> to <code>Maybe</code> in the Category of \(\) endofunctors.</p>
|
||||
<img style="float:left;width:50%" src="categories/img/mp/nattrans-list-maybe.png" alt="natural transformation commutative diagram"/>
|
||||
<p><code>toMaybe</code> is a natural transformation. It is also a morphism from <code>[]</code> to <code>Maybe</code> in the Category of \(\Hask\) endofunctors.</p>
|
||||
<img style="float:left;width:40%" src="categories/img/mp/nattrans-list-maybe.png" alt="natural transformation commutative diagram"/>
|
||||
<figure style="float:right;width:40%">
|
||||
<img src="categories/img/mp/list-maybe-endofunctor-morphism.png" alt="natural transformation commutative diagram"/>
|
||||
</figure>
|
||||
|
@ -716,8 +718,8 @@ toMaybe (x:xs) = Just x</pre>
|
|||
mToList Nothing = []
|
||||
mToList Just x = [x]</pre>
|
||||
</code>
|
||||
<p><code>toMaybe</code> is a natural transformation. It is also a morphism from <code>[]</code> to <code>Maybe</code> in the Category of \(\) endofunctors.</p>
|
||||
<img style="float:left;width:50%" src="categories/img/mp/nattrans-maybe-list.png" alt="natural transformation commutative diagram"/>
|
||||
<p><code>toMaybe</code> is a natural transformation. It is also a morphism from <code>[]</code> to <code>Maybe</code> in the Category of \(\Hask\) endofunctors.</p>
|
||||
<img style="float:left;width:40%" src="categories/img/mp/nattrans-maybe-list.png" alt="natural transformation commutative diagram"/>
|
||||
<figure style="float:right;width:40%">
|
||||
<img src="categories/img/mp/maybe-list-endofunctor-morphsm.png" alt="relation between [] and Maybe"/> <figcaption>There is <span class="red">no isomorphism</span>.<br/> Hint: <code>Bool</code> lists longer than 1. </figcaption>
|
||||
</figure>
|
||||
|
@ -727,14 +729,15 @@ mToList Just x = [x]</pre>
|
|||
<section class="slide">
|
||||
<h2 id="nat.-trans.-composition-generalization">Nat. Trans. <span class="and">&</span> Composition generalization</h2>
|
||||
<p>The Problem; example with lists:</p>
|
||||
<pre class="haskell"><code>f x = [x] ⇒ f 1 = [1] ⇒ (f.f) 1 = [[1]] ✗
|
||||
g x = [x+1] ⇒ g 1 = [2] ⇒ (g.g) 1 = ✗ ERROR [2]+1
|
||||
h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h.h) 1 = ✗ ERROR [2,3]+1</code></pre>
|
||||
<pre class="haskell"><code>f x = [x] ⇒ f 1 = [1] ⇒ (f.f) 1 = [[1]] ✗
|
||||
g x = [x+1] ⇒ g 1 = [2] ⇒ (g.g) 1 = ERROR [2]+1 ✗
|
||||
h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h.h) 1 = ERROR [2,3]+1 ✗ </code></pre>
|
||||
|
||||
<p>How to fix that? We want to construct an operator which is able to compose:</p>
|
||||
<p><code>f :: a -> F b</code> <span class="and">&</span> <code>f :: b -> F c</code>.</p>
|
||||
<p><code>f :: a -> F b</code> <span class="and">&</span> <code>g :: b -> F c</code>.</p>
|
||||
<p>More specifically we want to create an operator ◎ of type</p>
|
||||
<p><code>◎ :: (b -> F c) -> (a -> F b) -> (a -> F c)</code></p>
|
||||
<p><span class="smaller">Note if F = I, ◎ = ∘.</span></p>
|
||||
</section>
|
||||
<section class="slide">
|
||||
<h2 id="nat.-trans.-composition-generalization">Nat. Trans. <span class="and">&</span> Composition generalization</h2>
|
||||
|
@ -768,7 +771,7 @@ h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h.h) 1 = ✗ ERROR [2,3]+1</code></pre>
|
|||
<section class="slide">
|
||||
<h2 id="monads">Monads</h2>
|
||||
<p>We re-invented the <strong class="yellow">Monads</strong>!</p>
|
||||
<p>A monad is a triplet <code>(M,join,η)</code> where</p>
|
||||
<p>A monad is a triplet <code>(M,⊙,η)</code> where</p>
|
||||
<ul>
|
||||
<li>\(M\) an <span class="yellow">Endofunctor</span> (to type <code>a</code> associate <code>M a</code>)</li>
|
||||
<li>\(⊙:M×M→M\) a <span class="yellow">nat. trans.</span> (i.e. <code>⊙::M (M a) → M a</code>)</li>
|
||||
|
@ -781,8 +784,8 @@ h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h.h) 1 = ✗ ERROR [2,3]+1</code></pre>
|
|||
</ul>
|
||||
</section>
|
||||
<section class="slide">
|
||||
<h2 id="monads-are-just-monoids-14">Monads are just monoids (1/4)</h2>
|
||||
<p>A monoid is a triplet \((E,∙,e)\) s.t.</p>
|
||||
<h2 id="compare-with-monoid">Compare with Monoid</h2>
|
||||
<p>A Monoid is a triplet \((E,∙,e)\) s.t.</p>
|
||||
<ul>
|
||||
<li>\(E\) a set</li>
|
||||
<li>\(∙:E×E→E\)</li>
|
||||
|
@ -795,7 +798,7 @@ h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h.h) 1 = ✗ ERROR [2,3]+1</code></pre>
|
|||
</ul>
|
||||
</section>
|
||||
<section class="slide">
|
||||
<h2 id="monads">Monads</h2>
|
||||
<h2 id="monads-are-just-monoids">Monads are just Monoids</h2>
|
||||
<blockquote>
|
||||
<p>A Monad is just a monoid in the category of endofunctors, what's the problem?</p>
|
||||
</blockquote>
|
||||
|
@ -805,53 +808,44 @@ h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h.h) 1 = ✗ ERROR [2,3]+1</code></pre>
|
|||
</blockquote>
|
||||
</section>
|
||||
<section class="slide">
|
||||
<h2 id="monads-are-just-monoids-34">Monads are just Monoids (3/4)</h2>
|
||||
<p>Example: <code>Maybe</code> is a functor</p>
|
||||
<h2 id="list-monad">List Monad</h2>
|
||||
<p>Example: <code>List</code> is a functor</p>
|
||||
<ul>
|
||||
<li>\(M\) an <span class="yellow">Endofunctor</span></li>
|
||||
<li>\(⊙:M×M→M\) a nat. trans. (× is functor composition)</li>
|
||||
<li>\(η:I→M\) a nat. trans. (\(I\) identity functor)</li>
|
||||
<li>\([]\) an <span class="yellow">Endofunctor</span></li>
|
||||
<li>\(⊙:M×M→M\) a nat. trans. (<code>join :: M (M a) -> M a</code>)</li>
|
||||
<li>\(η:I→M\) a nat. trans.</li>
|
||||
</ul>
|
||||
<pre class="haskell"><code>-- In Haskell ⊙ is "join" in "Control.Monad"
|
||||
join :: Maybe (Maybe a) -> Maybe a
|
||||
join (Just (Just x)) = Just x
|
||||
join _ = Nothing
|
||||
join :: [[a]] -> [a]
|
||||
join = concat
|
||||
|
||||
-- In Haskell the "return" function (unfortunate name)
|
||||
η :: a -> Maybe a
|
||||
η x = Just x</code></pre>
|
||||
η :: a -> [a]
|
||||
η x = [x]</code></pre>
|
||||
|
||||
|
||||
</section>
|
||||
<section class="slide">
|
||||
<h2 id="monads-are-just-monoids-44">Monads are just Monoids (4/4)</h2>
|
||||
<p>Example: <code>Maybe</code> is a functor (<code>join</code> is ⊙)</p>
|
||||
<h2 id="list-monad">List Monad</h2>
|
||||
<p>Example: <code>List</code> is a functor (<code>join</code> is ⊙)</p>
|
||||
<ul>
|
||||
<li>\(M ⊙ (M ⊙ M) = (M ⊙ M) ⊙ M\)</li>
|
||||
<li>\(η ⊙ M = M = M ⊙ η\)</li>
|
||||
</ul>
|
||||
<pre class="nohighlight small"><code>join (Just (join (Just (Just x)))) = join (join (Just (Just (Just x))))
|
||||
join (Just (join (Just Nothing))) = join (join (Just (Just Nothing)))
|
||||
join (Just (join Nothing)) = join (join (Just Nothing))
|
||||
join Nothing = join (join Nothing)
|
||||
<pre class="nohighlight small"><code>
|
||||
join [ join [[x,y,...,z]] ] = join [[x,y,...,z]]
|
||||
= join (join [[[x,y,...,z]]])
|
||||
join (η [x]) = [x] = join [η x]</code></pre>
|
||||
|
||||
join (η (Just x)) = Just x = Just (η x)
|
||||
join (η Nothing) = Nothing = Nothing</code></pre>
|
||||
|
||||
<p>And <code>(Maybe,join,η)</code> is a monad.</p>
|
||||
<p>Therefore <code>([],join,η)</code> is a monad.</p>
|
||||
</section>
|
||||
<section class="slide">
|
||||
<h2 id="monads-generalize-composition">Monads generalize composition</h2>
|
||||
<p>Example with lists:</p>
|
||||
<pre class="haskell"><code>f=\x->[x] ⇒ f 1 = [1] ⇒ (f.f) 1 = [[1]]
|
||||
g=\x->[x+1] ⇒ g 1 = [2] ⇒ (g.g) 1 = ERROR [2]+1
|
||||
h=\x->[x+1,x*10] ⇒ h 1 = [2,10] ⇒ (h.h) 1 = ERROR [2,10]+1</code></pre>
|
||||
|
||||
<p>How to fix that? Kleisli composition</p>
|
||||
<p><code>f <=< g = \x -> join ((fmap f) (g x))</code></p>
|
||||
<pre class="haskell"><code>f=\x->[x] ⇒ f 1 = [1] ⇒ (f <=< f) 1 = [1]
|
||||
g=\x->[x+1] ⇒ g 1 = [2] ⇒ (g <=< g) 1 = [3]
|
||||
h=\x->[x+1,x*10] ⇒ h 1 = [2,10] ⇒ (h <=< h) 1 = [3,20,11,100]</code></pre>
|
||||
<h2 id="klesli-arrows">Klesli arrows</h2>
|
||||
<p>Now the composition works as expected. In Haskell ◎ is <code><=<</code> in <code>Control.Monad</code>.</p>
|
||||
<p><code>g <=< f = \x -> join ((fmap g) (f x))</code></p>
|
||||
<pre class="haskell"><code>f x = [x] ⇒ f 1 = [1] ⇒ (f <=< f) 1 = [1] ✓
|
||||
g x = [x+1] ⇒ g 1 = [2] ⇒ (g <=< g) 1 = [3] ✓
|
||||
h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h <=< h) 1 = [3,6,4,9] ✓</code></pre>
|
||||
|
||||
|
||||
</section>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<img class="right" src="categories/img/mindblown.gif" alt="mind blown"/>
|
||||
<p>Math vocabulary used in this presentation:</p>
|
||||
<blockquote>
|
||||
<p>Category, Morphism, Associativity, Preorder, Functor, Endofunctor, Categorial property, Commutative diagram, Isomorph, Initial, Dual, Monoid, Natural transformation, Monad, κατα-morphism, ...</p>
|
||||
<p>Category, Morphism, Associativity, Preorder, Functor, Endofunctor, Categorial property, Commutative diagram, Isomorph, Initial, Dual, Monoid, Natural transformation, Monad, Klesli arrows, κατα-morphism, ...</p>
|
||||
</blockquote>
|
||||
<img class="right" src="categories/img/readingcat.jpg" alt="lolcat"/>
|
||||
<table style="width:70%">
|
||||
|
|
|
@ -18,6 +18,7 @@ Math vocabulary used in this presentation:
|
|||
> Monoid,
|
||||
> Natural transformation,
|
||||
> Monad,
|
||||
> Klesli arrows,
|
||||
> κατα-morphism,
|
||||
> ...
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
|
||||
<p> A Category \(\mathcal{C}\) is defined by:</p>
|
||||
<ul>
|
||||
<li> <em>Objects (\(\ob{C}\))</em>,</li>
|
||||
<li> <em>Morphisms (\(\hom{C}\))</em>,</li>
|
||||
<li> a <em>Composition law (∘)</em></li>
|
||||
<li> <em>Objects <span class="yellow">\(\ob{C}\)</span></em>,</li>
|
||||
<li> <em>Morphisms <span class="yellow">\(\hom{C}\)</span></em>,</li>
|
||||
<li> a <em>Composition law <span class="yellow">(∘)</span></em></li>
|
||||
<li> obeying some <em>Properties</em>.</li>
|
||||
</ul>
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
<h2 id="haskell-kinds">Haskell Kinds</h2>
|
||||
<p>In Haskell some types can take type variable. Typically: <code>[a]</code>.</p>
|
||||
<p>In Haskell some types can take type variable(s). Typically: <code>[a]</code>.</p>
|
||||
<pre><code>data Tree a = Node a [Tree a]
|
||||
data CTree a b = CNode a [b]</code></pre>
|
||||
<p>Types have <em>kind</em>; The kind is to type what type is to function. Kind are the "type" for some types (so meta).</p>
|
||||
<p>Types have <em>kind</em>; The kind is to type what type is to function. Kind are the types for types (so meta).</p>
|
||||
<pre><code>Int, Char :: *
|
||||
[], Maybe, Tree :: * -> *
|
||||
CTree :: * -> * -> *
|
||||
[Int], Maybe Char, Tree [Int] :: *</code></pre>
|
||||
[Int], Maybe Char, Tree [Int] :: *
|
||||
CTree [Int] :: * -> *</code></pre>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
Haskell Kinds
|
||||
-------------
|
||||
|
||||
In Haskell some types can take type variable.
|
||||
In Haskell some types can take type variable(s).
|
||||
Typically: `[a]`.
|
||||
|
||||
~~~
|
||||
|
@ -11,11 +11,12 @@ data CTree a b = CNode a [b]
|
|||
|
||||
Types have _kind_;
|
||||
The kind is to type what type is to function.
|
||||
Kind are the "type" for some types (so meta).
|
||||
Kind are the types for types (so meta).
|
||||
|
||||
~~~
|
||||
Int, Char :: *
|
||||
[], Maybe, Tree :: * -> *
|
||||
CTree :: * -> * -> *
|
||||
[Int], Maybe Char, Tree [Int] :: *
|
||||
CTree [Int] :: * -> *
|
||||
~~~
|
||||
|
|
|
@ -10,7 +10,7 @@ f :: a -> [a] -- Many choices
|
|||
-- can only rearrange: duplicate/remove/reorder elements
|
||||
-- for example: the type of addOne isn't [a] -> [a]
|
||||
addOne l = map <span class="red">(+1)</span> l
|
||||
-- The (+1) force a to be a Num.</code></pre>
|
||||
-- The (+1) force 'a' to be a Num.</code></pre>
|
||||
|
||||
<p>
|
||||
<p><span class="small base01">★:<a href="http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf">Theorems for free!, Philip Wadler, 1989</a></span></p>
|
||||
|
|
|
@ -16,6 +16,6 @@ f :: a -> [a] -- Many choices
|
|||
-- can only rearrange: duplicate/remove/reorder elements
|
||||
-- for example: the type of addOne isn't [a] -> [a]
|
||||
addOne l = map <span class="red">(+1)</span> l
|
||||
-- The (+1) force a to be a Num.</code></pre>
|
||||
-- The (+1) force 'a' to be a Num.</code></pre>
|
||||
|
||||
<p><span class="small base01">★:<a href="http://ttic.uchicago.edu/~dreyer/course/papers/wadler.pdf">Theorems for free!, Philip Wadler, 1989</a></span>
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
<pre class="haskell"><code>data Maybe a = Just a | Nothing
|
||||
instance Functor Maybe where
|
||||
fmap :: (a -> b) -> (Maybe a -> Maybe b)
|
||||
fmap f (Just a) = f a
|
||||
fmap f (Just a) = Just (f a)
|
||||
fmap f Nothing = Nothing
|
||||
|
||||
fmap (+1) (Just 1) == 2
|
||||
fmap (+1) (Just 1) == Just 2
|
||||
fmap (+1) Nothing == Nothing
|
||||
fmap head (Just [1,2,3]) == Just 1</code></pre>
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
<h2 id="also-functor-inside-hask">Also Functor inside \(\Hask\)</h2>
|
||||
<p><code>length</code> can be seen as a Functor from the category <code>[a]</code> to the cateogry <code>Int</code>:</p>
|
||||
<ul class="left">
|
||||
<p>\(\mathtt{[a]}∈\ob{\Hask}\)</code> but is also a complete category. The same can be said for <code>Int</code>.</p>
|
||||
<p><code>length</code> is a Functor from the category <code>[a]</code> to the cateogry <code>Int</code>:</p>
|
||||
<ul class="left" style="max-width:40%">
|
||||
<li>\(\ob{\mathtt{[a]}}=\{∙\}\)</li>
|
||||
<li>\(\hom{\mathtt{[a]}}=\mathtt{[a]}\)</li>
|
||||
<li>\(∘=\mathtt{(++)}\)</li>
|
||||
</ul>
|
||||
<p class="left" style="margin:2em 3em">⇒</p>
|
||||
<ul class="left">
|
||||
<ul class="left" style="max-width:40%">
|
||||
<li>\(\ob{\mathtt{Int}}=\{∙\}\)</li>
|
||||
<li>\(\hom{\mathtt{Int}}=\mathtt{Int}\)</li>
|
||||
<li>\(∘=\mathtt{(+)}\)</li>
|
||||
|
|
|
@ -4,8 +4,8 @@ toTree :: [a] -> Tree a
|
|||
toTree [] = Empty
|
||||
toTree (x:xs) = Node x [toTree xs]</pre>
|
||||
</code>
|
||||
<p><code>toTree</code> is a natural transformation. It is also a morphism from <code>[]</code> to <code>Tree</code> in the Category of \(\) endofunctors.</p>
|
||||
<img style="float:left;width:50%" src="categories/img/mp/nattrans-list-tree.png" alt="natural transformation commutative diagram"/>
|
||||
<p><code>toTree</code> is a natural transformation. It is also a morphism from <code>[]</code> to <code>Tree</code> in the Category of \(\Hask\) endofunctors.</p>
|
||||
<img style="float:left;width:40%" src="categories/img/mp/nattrans-list-tree.png" alt="natural transformation commutative diagram"/>
|
||||
<figure style="float:right;width:40%">
|
||||
<img src="categories/img/mp/list-tree-endofunctor-morphism.png" alt="natural transformation commutative diagram"/>
|
||||
</figure>
|
||||
|
|
|
@ -8,9 +8,9 @@ toTree (x:xs) = Node x [toTree xs]</pre></code>
|
|||
|
||||
|
||||
`toTree` is a natural transformation.
|
||||
It is also a morphism from `[]` to `Tree` in the Category of \\(\Hask\\) endofunctors.
|
||||
It is also a morphism from `[]` to `Tree` in the Category of \\(\\Hask\\) endofunctors.
|
||||
|
||||
<img style="float:left;width:50%" src="categories/img/mp/nattrans-list-tree.png" alt="natural transformation commutative diagram"/>
|
||||
<img style="float:left;width:40%" src="categories/img/mp/nattrans-list-tree.png" alt="natural transformation commutative diagram"/>
|
||||
<figure style="float:right;width:40%">
|
||||
<img src="categories/img/mp/list-tree-endofunctor-morphism.png" alt="natural transformation commutative diagram"/>
|
||||
</figure>
|
||||
|
|
|
@ -4,8 +4,8 @@ toList :: Tree a -> [a]
|
|||
toList Empty = []
|
||||
toList (Node x l) = [x] ++ concat (map toList l)</pre>
|
||||
</code>
|
||||
<p><code>toList</code> is a natural transformation. It is also a morphism from <code>Tree</code> to <code>[]</code> in the Category of \(\) endofunctors.</p>
|
||||
<img style="float:left;width:50%" src="categories/img/mp/nattrans-tree-list.png" alt="natural transformation commutative diagram"/>
|
||||
<p><code>toList</code> is a natural transformation. It is also a morphism from <code>Tree</code> to <code>[]</code> in the Category of \(\Hask\) endofunctors.</p>
|
||||
<img style="float:left;width:40%" src="categories/img/mp/nattrans-tree-list.png" alt="natural transformation commutative diagram"/>
|
||||
<figure style="float:right;width:40%">
|
||||
<img src="categories/img/mp/tree-list-endofunctor-morphism.png" alt="natural transformation commutative diagram"/> <figcaption><code>toList . toTree = id</code> &<br/> <code>toTree . toList = id</code> <span style="visibility:hidden">&</span><br/> therefore <code>[]</code> & <code>Tree</code> are <span class="yellow">isomorph</span>. </figcaption>
|
||||
</figure>
|
||||
|
|
|
@ -8,9 +8,9 @@ toList (Node x l) = [x] ++ concat (map toList l)</pre></code>
|
|||
|
||||
|
||||
`toList` is a natural transformation.
|
||||
It is also a morphism from `Tree` to `[]` in the Category of \\(\Hask\\) endofunctors.
|
||||
It is also a morphism from `Tree` to `[]` in the Category of \\(\\Hask\\) endofunctors.
|
||||
|
||||
<img style="float:left;width:50%" src="categories/img/mp/nattrans-tree-list.png" alt="natural transformation commutative diagram"/>
|
||||
<img style="float:left;width:40%" src="categories/img/mp/nattrans-tree-list.png" alt="natural transformation commutative diagram"/>
|
||||
<figure style="float:right;width:40%">
|
||||
<img src="categories/img/mp/tree-list-endofunctor-morphism.png" alt="natural transformation commutative diagram"/>
|
||||
<figcaption><code>toList . toTree = id</code> &<br/> <code>toTree . toList = id</code> <span style="visibility:hidden">&</span><br/>
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
toMaybe [] = Nothing
|
||||
toMaybe (x:xs) = Just x</pre>
|
||||
</code>
|
||||
<p><code>toMaybe</code> is a natural transformation. It is also a morphism from <code>[]</code> to <code>Maybe</code> in the Category of \(\) endofunctors.</p>
|
||||
<img style="float:left;width:50%" src="categories/img/mp/nattrans-list-maybe.png" alt="natural transformation commutative diagram"/>
|
||||
<p><code>toMaybe</code> is a natural transformation. It is also a morphism from <code>[]</code> to <code>Maybe</code> in the Category of \(\Hask\) endofunctors.</p>
|
||||
<img style="float:left;width:40%" src="categories/img/mp/nattrans-list-maybe.png" alt="natural transformation commutative diagram"/>
|
||||
<figure style="float:right;width:40%">
|
||||
<img src="categories/img/mp/list-maybe-endofunctor-morphism.png" alt="natural transformation commutative diagram"/>
|
||||
</figure>
|
||||
|
|
|
@ -7,9 +7,9 @@ toMaybe (x:xs) = Just x</pre></code>
|
|||
|
||||
|
||||
`toMaybe` is a natural transformation.
|
||||
It is also a morphism from `[]` to `Maybe` in the Category of \\(\Hask\\) endofunctors.
|
||||
It is also a morphism from `[]` to `Maybe` in the Category of \\(\\Hask\\) endofunctors.
|
||||
|
||||
<img style="float:left;width:50%" src="categories/img/mp/nattrans-list-maybe.png" alt="natural transformation commutative diagram"/>
|
||||
<img style="float:left;width:40%" src="categories/img/mp/nattrans-list-maybe.png" alt="natural transformation commutative diagram"/>
|
||||
<figure style="float:right;width:40%">
|
||||
<img src="categories/img/mp/list-maybe-endofunctor-morphism.png" alt="natural transformation commutative diagram"/>
|
||||
</figure>
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
mToList Nothing = []
|
||||
mToList Just x = [x]</pre>
|
||||
</code>
|
||||
<p><code>toMaybe</code> is a natural transformation. It is also a morphism from <code>[]</code> to <code>Maybe</code> in the Category of \(\) endofunctors.</p>
|
||||
<img style="float:left;width:50%" src="categories/img/mp/nattrans-maybe-list.png" alt="natural transformation commutative diagram"/>
|
||||
<p><code>toMaybe</code> is a natural transformation. It is also a morphism from <code>[]</code> to <code>Maybe</code> in the Category of \(\Hask\) endofunctors.</p>
|
||||
<img style="float:left;width:40%" src="categories/img/mp/nattrans-maybe-list.png" alt="natural transformation commutative diagram"/>
|
||||
<figure style="float:right;width:40%">
|
||||
<img src="categories/img/mp/maybe-list-endofunctor-morphsm.png" alt="relation between [] and Maybe"/> <figcaption>There is <span class="red">no isomorphism</span>.<br/> Hint: <code>Bool</code> lists longer than 1. </figcaption>
|
||||
</figure>
|
||||
|
|
|
@ -7,9 +7,9 @@ mToList Just x = [x]</pre></code>
|
|||
|
||||
|
||||
`toMaybe` is a natural transformation.
|
||||
It is also a morphism from `[]` to `Maybe` in the Category of \\(\Hask\\) endofunctors.
|
||||
It is also a morphism from `[]` to `Maybe` in the Category of \\(\\Hask\\) endofunctors.
|
||||
|
||||
<img style="float:left;width:50%" src="categories/img/mp/nattrans-maybe-list.png" alt="natural transformation commutative diagram"/>
|
||||
<img style="float:left;width:40%" src="categories/img/mp/nattrans-maybe-list.png" alt="natural transformation commutative diagram"/>
|
||||
<figure style="float:right;width:40%">
|
||||
<img src="categories/img/mp/maybe-list-endofunctor-morphsm.png" alt="relation between [] and Maybe"/>
|
||||
<figcaption>There is <span class="red">no isomorphism</span>.<br/>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
<h2 id="nat.-trans.-composition-generalization">Nat. Trans. & Composition generalization</h2>
|
||||
<p>The Problem; example with lists:</p>
|
||||
<pre class="haskell"><code>f x = [x] ⇒ f 1 = [1] ⇒ (f.f) 1 = [[1]] ✗
|
||||
g x = [x+1] ⇒ g 1 = [2] ⇒ (g.g) 1 = ✗ ERROR [2]+1
|
||||
h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h.h) 1 = ✗ ERROR [2,3]+1</code></pre>
|
||||
<pre class="haskell"><code>f x = [x] ⇒ f 1 = [1] ⇒ (f.f) 1 = [[1]] ✗
|
||||
g x = [x+1] ⇒ g 1 = [2] ⇒ (g.g) 1 = ERROR [2]+1 ✗
|
||||
h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h.h) 1 = ERROR [2,3]+1 ✗ </code></pre>
|
||||
|
||||
<p>How to fix that? We want to construct an operator which is able to compose:</p>
|
||||
<p><code>f :: a -> F b</code> & <code>f :: b -> F c</code>.</p>
|
||||
<p><code>f :: a -> F b</code> & <code>g :: b -> F c</code>.</p>
|
||||
<p>More specifically we want to create an operator ◎ of type</p>
|
||||
<p><code>◎ :: (b -> F c) -> (a -> F b) -> (a -> F c)</code></p>
|
||||
<p><span class="smaller">Note if F = I, ◎ = ∘.</span></p>
|
||||
|
|
|
@ -3,14 +3,16 @@ Nat. Trans. & Composition generalization
|
|||
|
||||
The Problem; example with lists:
|
||||
|
||||
<pre class="haskell"><code>f x = [x] ⇒ f 1 = [1] ⇒ (f.f) 1 = [[1]] ✗
|
||||
g x = [x+1] ⇒ g 1 = [2] ⇒ (g.g) 1 = ✗ ERROR [2]+1
|
||||
h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h.h) 1 = ✗ ERROR [2,3]+1</code></pre>
|
||||
<pre class="haskell"><code>f x = [x] ⇒ f 1 = [1] ⇒ (f.f) 1 = [[1]] ✗
|
||||
g x = [x+1] ⇒ g 1 = [2] ⇒ (g.g) 1 = ERROR [2]+1 ✗
|
||||
h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h.h) 1 = ERROR [2,3]+1 ✗ </code></pre>
|
||||
|
||||
How to fix that? We want to construct an operator which is able to compose:
|
||||
|
||||
`f :: a -> F b` & `f :: b -> F c`.
|
||||
`f :: a -> F b` & `g :: b -> F c`.
|
||||
|
||||
More specifically we want to create an operator ◎ of type
|
||||
|
||||
`◎ :: (b -> F c) -> (a -> F b) -> (a -> F c)`
|
||||
|
||||
<span class="smaller">Note if F = I, ◎ = ∘.</span>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<h2 id="monads">Monads</h2>
|
||||
<p>We re-invented the <strong class="yellow">Monads</strong>!</p>
|
||||
<p>A monad is a triplet <code>(M,join,η)</code> where</p>
|
||||
<p>A monad is a triplet <code>(M,⊙,η)</code> where</p>
|
||||
<ul>
|
||||
<li>\(M\) an <span class="yellow">Endofunctor</span> (to type <code>a</code> associate <code>M a</code>)</li>
|
||||
<li>\(⊙:M×M→M\) a <span class="yellow">nat. trans.</span> (i.e. <code>⊙::M (M a) → M a</code>)</li>
|
||||
|
|
|
@ -3,7 +3,7 @@ Monads
|
|||
|
||||
We re-invented the <strong class="yellow">Monads</strong>!
|
||||
|
||||
A monad is a triplet `(M,join,η)` where
|
||||
A monad is a triplet `(M,⊙,η)` where
|
||||
|
||||
- \\(M\\) an <span class="yellow">Endofunctor</span> (to type `a` associate `M a`)
|
||||
- \\(⊙:M×M→M\\) a <span class="yellow">nat. trans.</span> (i.e. `⊙::M (M a) → M a`)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<h2 id="monads-are-just-monoids-14">Monads are just monoids (1/4)</h2>
|
||||
<p>A monoid is a triplet \((E,∙,e)\) s.t.</p>
|
||||
<h2 id="compare-with-monoid">Compare with Monoid</h2>
|
||||
<p>A Monoid is a triplet \((E,∙,e)\) s.t.</p>
|
||||
<ul>
|
||||
<li>\(E\) a set</li>
|
||||
<li>\(∙:E×E→E\)</li>
|
|
@ -1,7 +1,7 @@
|
|||
Monads are just monoids (1/4)
|
||||
-----------------------------
|
||||
Compare with Monoid
|
||||
-------------------
|
||||
|
||||
A monoid is a triplet \\((E,∙,e)\\) s.t.
|
||||
A Monoid is a triplet \\((E,∙,e)\\) s.t.
|
||||
|
||||
- \\(E\\) a set
|
||||
- \\(∙:E×E→E\\)
|
|
@ -1,4 +1,4 @@
|
|||
<h2 id="monads">Monads</h2>
|
||||
<h2 id="monads-are-just-monoids">Monads are just Monoids</h2>
|
||||
<blockquote>
|
||||
<p>A Monad is just a monoid in the category of endofunctors, what's the problem?</p>
|
||||
</blockquote>
|
|
@ -1,5 +1,5 @@
|
|||
Monads
|
||||
------
|
||||
Monads are just Monoids
|
||||
-----------------------
|
||||
|
||||
> A Monad is just a monoid in the category of endofunctors, what's the problem?
|
||||
|
|
@ -1,17 +1,16 @@
|
|||
<h2 id="monads-are-just-monoids-34">Monads are just Monoids (3/4)</h2>
|
||||
<p>Example: <code>Maybe</code> is a functor</p>
|
||||
<h2 id="list-monad">List Monad</h2>
|
||||
<p>Example: <code>List</code> is a functor</p>
|
||||
<ul>
|
||||
<li>\(M\) an <span class="yellow">Endofunctor</span></li>
|
||||
<li>\(⊙:M×M→M\) a nat. trans. (× is functor composition)</li>
|
||||
<li>\(η:I→M\) a nat. trans. (\(I\) identity functor)</li>
|
||||
<li>\([]\) an <span class="yellow">Endofunctor</span></li>
|
||||
<li>\(⊙:M×M→M\) a nat. trans. (<code>join :: M (M a) -> M a</code>)</li>
|
||||
<li>\(η:I→M\) a nat. trans.</li>
|
||||
</ul>
|
||||
<pre class="haskell"><code>-- In Haskell ⊙ is "join" in "Control.Monad"
|
||||
join :: Maybe (Maybe a) -> Maybe a
|
||||
join (Just (Just x)) = Just x
|
||||
join _ = Nothing
|
||||
join :: [[a]] -> [a]
|
||||
join = concat
|
||||
|
||||
-- In Haskell the "return" function (unfortunate name)
|
||||
η :: a -> Maybe a
|
||||
η x = Just x</code></pre>
|
||||
η :: a -> [a]
|
||||
η x = [x]</code></pre>
|
||||
|
||||
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
Monads are just Monoids (3/4)
|
||||
-----------------------------
|
||||
List Monad
|
||||
----------
|
||||
|
||||
Example: `Maybe` is a functor
|
||||
Example: `List` is a functor
|
||||
|
||||
- \\(M\\) an <span class="yellow">Endofunctor</span>
|
||||
- \\(⊙:M×M→M\\) a nat. trans. (× is functor composition)
|
||||
- \\(η:I→M\\) a nat. trans. (\\(I\\) identity functor)
|
||||
- \\([]\\) an <span class="yellow">Endofunctor</span>
|
||||
- \\(⊙:M×M→M\\) a nat. trans. (`join :: M (M a) -> M a`)
|
||||
- \\(η:I→M\\) a nat. trans.
|
||||
|
||||
<pre class="haskell"><code>-- In Haskell ⊙ is "join" in "Control.Monad"
|
||||
join :: Maybe (Maybe a) -> Maybe a
|
||||
join (Just (Just x)) = Just x
|
||||
join _ = Nothing
|
||||
join :: [[a]] -> [a]
|
||||
join = concat
|
||||
|
||||
-- In Haskell the "return" function (unfortunate name)
|
||||
η :: a -> Maybe a
|
||||
η x = Just x</code></pre>
|
||||
η :: a -> [a]
|
||||
η x = [x]</code></pre>
|
||||
|
|
|
@ -1,15 +1,12 @@
|
|||
<h2 id="monads-are-just-monoids-44">Monads are just Monoids (4/4)</h2>
|
||||
<p>Example: <code>Maybe</code> is a functor (<code>join</code> is ⊙)</p>
|
||||
<h2 id="list-monad">List Monad</h2>
|
||||
<p>Example: <code>List</code> is a functor (<code>join</code> is ⊙)</p>
|
||||
<ul>
|
||||
<li>\(M ⊙ (M ⊙ M) = (M ⊙ M) ⊙ M\)</li>
|
||||
<li>\(η ⊙ M = M = M ⊙ η\)</li>
|
||||
</ul>
|
||||
<pre class="nohighlight small"><code>join (Just (join (Just (Just x)))) = join (join (Just (Just (Just x))))
|
||||
join (Just (join (Just Nothing))) = join (join (Just (Just Nothing)))
|
||||
join (Just (join Nothing)) = join (join (Just Nothing))
|
||||
join Nothing = join (join Nothing)
|
||||
<pre class="nohighlight small"><code>
|
||||
join [ join [[x,y,...,z]] ] = join [[x,y,...,z]]
|
||||
= join (join [[[x,y,...,z]]])
|
||||
join (η [x]) = [x] = join [η x]</code></pre>
|
||||
|
||||
join (η (Just x)) = Just x = Just (η x)
|
||||
join (η Nothing) = Nothing = Nothing</code></pre>
|
||||
|
||||
<p>And <code>(Maybe,join,η)</code> is a monad.</p>
|
||||
<p>Therefore <code>([],join,η)</code> is a monad.</p>
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
Monads are just Monoids (4/4)
|
||||
-----------------------------
|
||||
List Monad
|
||||
----------
|
||||
|
||||
Example: `Maybe` is a functor (`join` is ⊙)
|
||||
Example: `List` is a functor (`join` is ⊙)
|
||||
|
||||
- \\(M ⊙ (M ⊙ M) = (M ⊙ M) ⊙ M\\)
|
||||
- \\(η ⊙ M = M = M ⊙ η\\)
|
||||
|
||||
<pre class="nohighlight small"><code>join (Just (join (Just (Just x)))) = join (join (Just (Just (Just x))))
|
||||
join (Just (join (Just Nothing))) = join (join (Just (Just Nothing)))
|
||||
join (Just (join Nothing)) = join (join (Just Nothing))
|
||||
join Nothing = join (join Nothing)
|
||||
<pre class="nohighlight small"><code>
|
||||
join [ join [[x,y,...,z]] ] = join [[x,y,...,z]]
|
||||
= join (join [[[x,y,...,z]]])
|
||||
join (η [x]) = [x] = join [η x]</code></pre>
|
||||
|
||||
join (η (Just x)) = Just x = Just (η x)
|
||||
join (η Nothing) = Nothing = Nothing</code></pre>
|
||||
|
||||
And `(Maybe,join,η)` is a monad.
|
||||
Therefore `([],join,η)` is a monad.
|
||||
|
|
|
@ -1,13 +1,8 @@
|
|||
<h2 id="monads-generalize-composition">Monads generalize composition</h2>
|
||||
<p>Example with lists:</p>
|
||||
<pre class="haskell"><code>f=\x->[x] ⇒ f 1 = [1] ⇒ (f.f) 1 = [[1]]
|
||||
g=\x->[x+1] ⇒ g 1 = [2] ⇒ (g.g) 1 = ERROR [2]+1
|
||||
h=\x->[x+1,x*10] ⇒ h 1 = [2,10] ⇒ (h.h) 1 = ERROR [2,10]+1</code></pre>
|
||||
|
||||
<p>How to fix that? Kleisli composition</p>
|
||||
<p><code>f <=< g = \x -> join ((fmap f) (g x))</code></p>
|
||||
<pre class="haskell"><code>f=\x->[x] ⇒ f 1 = [1] ⇒ (f <=< f) 1 = [1]
|
||||
g=\x->[x+1] ⇒ g 1 = [2] ⇒ (g <=< g) 1 = [3]
|
||||
h=\x->[x+1,x*10] ⇒ h 1 = [2,10] ⇒ (h <=< h) 1 = [3,20,11,100]</code></pre>
|
||||
<h2 id="klesli-arrows">Klesli arrows</h2>
|
||||
<p>Now the composition works as expected. In Haskell ◎ is <code><=<</code> in <code>Control.Monad</code>.</p>
|
||||
<p><code>g <=< f = \x -> join ((fmap g) (f x))</code></p>
|
||||
<pre class="haskell"><code>f x = [x] ⇒ f 1 = [1] ⇒ (f <=< f) 1 = [1] ✓
|
||||
g x = [x+1] ⇒ g 1 = [2] ⇒ (g <=< g) 1 = [3] ✓
|
||||
h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h <=< h) 1 = [3,6,4,9] ✓</code></pre>
|
||||
|
||||
|
||||
|
|
|
@ -1,16 +1,10 @@
|
|||
Monads generalize composition
|
||||
-----------------------------
|
||||
Klesli arrows
|
||||
-------------
|
||||
|
||||
Example with lists:
|
||||
Now the composition works as expected. In Haskell ◎ is `<=<` in `Control.Monad`.
|
||||
|
||||
<pre class="haskell"><code>f=\x->[x] ⇒ f 1 = [1] ⇒ (f.f) 1 = [[1]]
|
||||
g=\x->[x+1] ⇒ g 1 = [2] ⇒ (g.g) 1 = ERROR [2]+1
|
||||
h=\x->[x+1,x*10] ⇒ h 1 = [2,10] ⇒ (h.h) 1 = ERROR [2,10]+1</code></pre>
|
||||
`g <=< f = \x -> join ((fmap g) (f x))`
|
||||
|
||||
How to fix that? Kleisli composition
|
||||
|
||||
`f <=< g = \x -> join ((fmap f) (g x))`
|
||||
|
||||
<pre class="haskell"><code>f=\x->[x] ⇒ f 1 = [1] ⇒ (f <=< f) 1 = [1]
|
||||
g=\x->[x+1] ⇒ g 1 = [2] ⇒ (g <=< g) 1 = [3]
|
||||
h=\x->[x+1,x*10] ⇒ h 1 = [2,10] ⇒ (h <=< h) 1 = [3,20,11,100]</code></pre>
|
||||
<pre class="haskell"><code>f x = [x] ⇒ f 1 = [1] ⇒ (f <=< f) 1 = [1] ✓
|
||||
g x = [x+1] ⇒ g 1 = [2] ⇒ (g <=< g) 1 = [3] ✓
|
||||
h x = [x+1,x*3] ⇒ h 1 = [2,3] ⇒ (h <=< h) 1 = [3,6,4,9] ✓</code></pre>
|
||||
|
|
|
@ -36,6 +36,12 @@
|
|||
body.deck-container {
|
||||
width: 100%;
|
||||
padding: 0; }
|
||||
body.deck-container .goto-form {
|
||||
font-size: 22px;
|
||||
background-color: #073642;
|
||||
label-font-shadow: none;
|
||||
label-font-color: #93a1a1;
|
||||
#goto-slide-height: 50px; }
|
||||
|
||||
.deck-container {
|
||||
font-family: "ComputerModernSansSerif", Helvetica, sans-serif;
|
||||
|
@ -882,7 +888,7 @@ body.deck-container {
|
|||
.deck-container #social:hover {
|
||||
opacity: 1; }
|
||||
.deck-container .popularblock {
|
||||
width: 30.3333%;
|
||||
width: 30.333%;
|
||||
margin: 0 1.5%;
|
||||
float: left; }
|
||||
.deck-container .popularblock figure {
|
||||
|
@ -904,10 +910,10 @@ body.deck-container {
|
|||
|
||||
@media only screen and (max-width: 3400px) {
|
||||
.deck-container {
|
||||
font-size: 5em; } }
|
||||
font-size: 3.5em; } }
|
||||
@media only screen and (max-width: 1920px) {
|
||||
.deck-container {
|
||||
font-size: 4em; } }
|
||||
font-size: 3.5em; } }
|
||||
@media only screen and (max-width: 1380px) {
|
||||
.deck-container {
|
||||
font-size: 2.5em; } }
|
||||
|
|
|
@ -187,6 +187,14 @@ $secondTextColor: $base1
|
|||
body.deck-container
|
||||
width: 100%
|
||||
padding: 0
|
||||
.goto-form
|
||||
font-size: 22px
|
||||
background-color: $base02
|
||||
label:
|
||||
font-shadow: none
|
||||
font-color: $base1
|
||||
#goto-slide:
|
||||
height: 50px
|
||||
|
||||
.deck-container
|
||||
.base03
|
||||
|
@ -1144,10 +1152,10 @@ body.deck-container
|
|||
|
||||
@media only screen and (max-width: 3400px)
|
||||
.deck-container
|
||||
font-size: 5em
|
||||
font-size: 3.5em
|
||||
@media only screen and (max-width: 1920px)
|
||||
.deck-container
|
||||
font-size: 4em
|
||||
font-size: 3.5em
|
||||
@media only screen and (max-width: 1380px)
|
||||
.deck-container
|
||||
font-size: 2.5em
|
||||
|
|
Loading…
Reference in a new issue