Last active
March 27, 2016 09:43
-
-
Save jorpic/924c48aa888fc0870f38 to your computer and use it in GitHub Desktop.
Haskell Meetup 2015-12-06
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!doctype html> | |
| <html> | |
| <head> | |
| <meta charset="utf-8"> | |
| <link href='https://fonts.googleapis.com/css?family=Raleway:500' rel='stylesheet' type='text/css'> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/styles/github.min.css"> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/highlight.min.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.0.0/languages/haskell.min.js"></script> | |
| <style> | |
| @page { | |
| size: landscape; | |
| } | |
| body { | |
| font-family: sans-serif; | |
| font-size: 4vh; | |
| } | |
| section { | |
| display: flex; | |
| flex-direction: column; | |
| align-items: center; | |
| justify-content: center; | |
| height: 80vh; | |
| padding: 10vh 0 10vh 0; | |
| page-break-after: always; | |
| } | |
| pre { | |
| width: min-content; | |
| width: -moz-min-content; | |
| width: -webkit-min-content; | |
| line-height: 140%; | |
| } | |
| img { | |
| display: block; | |
| height: 60vh; | |
| width: auto; | |
| } | |
| li { | |
| margin-bottom: 0.7em; | |
| } | |
| .email { | |
| font-size: 80%; | |
| opacity: 0.8; | |
| } | |
| .logo { | |
| font-family: 'Raleway', sans-serif; | |
| font-size: 8vh; | |
| color: #333; | |
| opacity: 0.8; | |
| } | |
| .logo .flipA { | |
| display: inline-block; | |
| -moz-transform: scale(1, -1); | |
| -webkit-transform: scale(1, -1); | |
| transform: scale(1, -1); | |
| color: #48045a; | |
| } | |
| .logo .flipE { | |
| display: inline-block; | |
| -moz-transform: scale(-1, 1); | |
| -webkit-transform: scale(-1, 1); | |
| transform: scale(-1, 1); | |
| color: #48045a; | |
| } | |
| #arrow-table th, | |
| #arrow-table td { | |
| text-align: center; | |
| padding: 0.2em 1em 0.2em 1em; | |
| } | |
| pre code.error { | |
| background: pink; | |
| } | |
| </style> | |
| </head> | |
| <body spellcheck=false> | |
| <section id="start"> | |
| <h1>Зависимые типы в GHC 8</h1> | |
| <p>Максим Талдыкин</p> | |
| <p class="email">[email protected]</p> | |
| </section> | |
| <section id="what"> | |
| <h1>Что такое?</h1> | |
| </section> | |
| <section id="what/sorts"> | |
| <pre><code class="haskell"> | |
| Just 1 : Maybe Int : * : □ | |
| Maybe : * -> * : □ | |
| Vec Int Z : * : □ | |
| Vec : * -> Nat -> * : □ | |
| </code></pre> | |
| </section> | |
| <section id="what/arrows"> | |
| <pre><code class="haskell"> | |
| map : forall a b. (a -> b) -> [a] -> [b] | |
| map f (x:xs) = f x : map f xs | |
| map f [] = [] | |
| </code></pre> | |
| </section> | |
| <section id="what/core"> | |
| <pre><code class="haskell"> | |
| map :: forall a b. (a -> b) -> [a] -> [b] | |
| map = | |
| \ (@a) | |
| (@b) | |
| (f :: a -> b) | |
| (ds :: [a]) -> | |
| case ds of | |
| [] -> GHC.Types.[] @b | |
| : x xs -> | |
| GHC.Types.: @b (f x) (map @a @b f xs) | |
| </code></pre> | |
| </section> | |
| <section id="what/forall"> | |
| <pre><code class="haskell"> | |
| forall | |
| (a :: *) | |
| (b :: *) | |
| (f :: a -> b) | |
| (xs :: [a]) | |
| . [b] | |
| </code></pre> | |
| </section> | |
| <section id="what/pi"> | |
| <pre><code class="haskell"> | |
| replicate :: pi (n : Nat) -> a -> Vec a n | |
| replicate Z _ = Nil | |
| replicate (S m) x = x :> replicate m a | |
| </code></pre> | |
| </section> | |
| <section id="what/table"> | |
| <table id="arrow-table"> | |
| <tr><th> </th><th>vis</th><th>dep</th><th>rel</th></tr> | |
| <tr><td>forall (a : *). a </td><td> - </td><td> + </td><td> - </td></tr> | |
| <tr><td>a -> a </td><td> + </td><td> - </td><td> + </td></tr> | |
| <tr><td>Monad m => m a </td><td> - </td><td> - </td><td> + </td></tr> | |
| <tr><td>pi (a : Bool). f a </td><td> - </td><td> + </td><td> + </td></tr> | |
| <tr><td>pi (a : Bool) -> f a</td><td> + </td><td> + </td><td> + </td></tr> | |
| </table> | |
| </section> | |
| <section id="what/star-in-star"> | |
| <h1>* : *</h1> | |
| <h1>pi</h1> | |
| </section> | |
| <section id="why"> | |
| <h1>Зачем?</h1> | |
| </section> | |
| <section id="why/good-bad"> | |
| <h1>zipWithN, mapT</h1> | |
| <h1>tail []</h1> | |
| </section> | |
| <section id="why/strncpy"> | |
| <pre><code class="haskell"> | |
| strncpy | |
| :: forall (p q :: Nat) | |
| => (LE n p ~ True, LE n q ~ True) | |
| . pi (n :: Nat) | |
| -> Ptr Char p | |
| -> Ptr Char q | |
| -> IO () | |
| </code></pre> | |
| </section> | |
| <section id="why/examples"> | |
| <ul> | |
| <li> | |
| <a href="http://www.staff.science.uu.nl/~swier004/Publications/piware.pdf">Π-Ware: Hardware Description</a> | |
| <ul><li>Swierstra et al., 2015</li></ul> | |
| </li> | |
| <li> | |
| <a href="https://eb.host.cs.st-andrews.ac.uk/writings/fi-cbc.pdf">Correct-by-Construction Concurrency</a> | |
| <ul><li>Brady & Hammond, 2009</li></ul> | |
| </li> | |
| <li> | |
| <a href="http://www.cs.cmu.edu/~jamiemmt/papers/ml10sectyp.pdf">Security-Typed Programming</a> | |
| <ul><li>Morgenstern & Licata, 2010 </li></ul> | |
| </li> | |
| </ul> | |
| </section> | |
| <section id="tf"> | |
| <h1>Type Families</h1> | |
| </section> | |
| <section id="tf/nat"> | |
| <pre><code class="haskell"> | |
| data Nat = Z | S Nat | |
| type family | |
| (m :: Nat) :+ (n :: Nat) :: Nat | |
| where | |
| Z :+ n = n | |
| (S k) :+ n = S (k :+ n) | |
| -- Vec a m -> Vec a n -> Vec a (m :+ n) | |
| </code></pre> | |
| </section> | |
| <section id="gadt"> | |
| <h1>GADTs</h1> | |
| Generalized Algebraic Data Types | |
| </section> | |
| <section id="gadt/vec"> | |
| <pre><code class="haskell"> | |
| data Vec :: Nat -> * -> * | |
| Nil :: Vec Z a | |
| (:>) :: a -> Vec n a -> Vec (S n) a | |
| </code></pre> | |
| </section> | |
| <section id="gadt/vec-eq"> | |
| <pre><code class="haskell"> | |
| data Vec (n :: Nat) (a :: *) :: * where | |
| Nil :: n ~ Z => Nil n a | |
| (:>) :: forall (m :: Nat) | |
| . n ~ S m | |
| => a -> Vec m a -> Vec n a | |
| </code></pre> | |
| </section> | |
| <section id="gadt/vec-pm"> | |
| <pre><code class="haskell"> | |
| tail :: Vec (S k) a -> Vec k a | |
| tail (_ :> xs) = xs | |
| -- (m :: Nat) (S k ~ S m) | |
| </code></pre> | |
| </section> | |
| <section id="gadt/vec-concat"> | |
| <pre><code class="haskell"> | |
| type family | |
| (v :: Vec a m) :++ (w :: Vec a n) :: Vec a k | |
| where | |
| Nil :++ w = w | |
| (x :> xs) :++ w = x :> (xs :++ w) | |
| </code></pre> | |
| </section> | |
| <section id="gadt/vec-concat-error"> | |
| <pre><code class="haskell"> | |
| type family | |
| (v :: Vec a m) :++ (w :: Vec a n) :: Vec a k | |
| where | |
| Nil :++ w = w | |
| (x :> xs) :++ w = x :> (xs :++ w) | |
| </code></pre> | |
| <pre><code class="error"> | |
| ‘Vec’ of kind ‘* -> Nat -> *’ is not promotable | |
| In the kind ‘Vec a m’ | |
| </code></pre> | |
| </section> | |
| <section id="gadt/vec-kind"> | |
| <pre><code class="haskell"> | |
| Vec :: □ -> □ -> □ | |
| </code></pre> | |
| </section> | |
| <section id="sing/replicate-pi"> | |
| <pre><code class="haskell"> | |
| replicate :: pi (n :: Nat) -> a -> Vec a n | |
| replicate Z a = Nil | |
| replicate (S m) a = a :> replicate m a | |
| </code></pre> | |
| </section> | |
| <section id="sing/nat"> | |
| <pre><code class="haskell"> | |
| data Nat = Z | S Nat | |
| data Nat's :: Nat -> * where | |
| Z's :: Nat's Z | |
| S's :: Nat's n -> Nat's (S n) | |
| -- S's Z's :: Nat's (S Z) | |
| </code></pre> | |
| </section> | |
| <section id="sing/replicate-sing"> | |
| <pre><code class="haskell"> | |
| replicate :: Nat's n -> a -> Vec a n | |
| replicate Z's a = Nil | |
| replicate (S's m) a = a :> replicate m a | |
| </code></pre> | |
| </section> | |
| <section id="suddenly"> | |
| <h1>Они уже здесь!</h1> | |
| </section> | |
| <section id="singletons"> | |
| <h1>Singleton types here</h1> | |
| <h1>Singleton types there</h1> | |
| <h1>Singleton types everywhere</h1> | |
| <p>Monnier & Haguenauer, 2009</p> | |
| </section> | |
| <section id="hasochism"> | |
| <h1>Hasochism</h1> | |
| <p>Lindley & mcBride, 2013</p> | |
| </section> | |
| <section id="gadt/fin"> | |
| <pre><code class="haskell"> | |
| data Fin :: Nat -> * where | |
| FZ :: Fin (S n) | |
| FS :: Fin n -> Fin (S n) | |
| </code></pre> | |
| </section> | |
| <section id="gadt/lookup-pi"> | |
| <pre><code class="haskell"> | |
| lookup :: pi (f :: Fin n) -> Vec a n -> a | |
| lookup FZ (x :> _) = x | |
| lookup (FS i) (_ :> xs) = lookup i xs | |
| </code></pre> | |
| </section> | |
| <section id="gadt/fin-sing"> | |
| <pre><code class="haskell"> | |
| data Fin's (n :: Nat) (f :: Fin n) :: * where | |
| FZ's :: Fin's (S m) FZ | |
| FS's :: Fin's m g -> Fin's (S m) (FS g) | |
| -- FS's FZ's :: Fin's 4 (FS FZ :: Fin 4) | |
| </code></pre> | |
| </section> | |
| <section id="gadt/fin-sing-error"> | |
| <pre><code class="haskell"> | |
| data Fin's (n :: Nat) (f :: Fin n) :: * where | |
| FZ's :: Fin's (S m) FZ | |
| FS's :: Fin's m g -> Fin's (S m) (FS g) | |
| </code></pre> | |
| <pre><code class="error"> | |
| Kind variable also used as type variable: ‘n’ | |
| In the data type declaration for ‘Fin's’ | |
| </code></pre> | |
| </section> | |
| <section id="servant"> | |
| <pre><code class="haskell"> | |
| get "/Contract/:id" $ do | |
| intParam "id" >>= queryDb "Contract" >>= json | |
| type API | |
| = "Contract" | |
| :> Capture "id" Int | |
| :> Get '[JSON] Contract | |
| </code></pre> | |
| </section> | |
| <section id="servant/svc"> | |
| <pre><code class="haskell"> | |
| type Api | |
| = "Contract" | |
| :> Capture "id" Int | |
| :> RoleFilter "Contract" "owner" '[43, 265] | |
| :> Get '[JSON] (Obj Contract) | |
| </code></pre> | |
| </section> | |
| <section id="servant/data-model"> | |
| <pre><code class="haskell"> | |
| data User (fieldName :: Symbol) where | |
| Id :: Int -> User "id" | |
| Name :: Text -> User "name" | |
| Roles :: [Vector (Ref Role)] -> User "roles" | |
| data Contract (fieldName :: Symbol) where | |
| Id :: Int -> Contract "id" | |
| Owner :: Ref Role -> Contract "owner" | |
| type family TableName (m :: Symbol -> *) :: Symbol | |
| type instance TableName User = "User" | |
| type instance TableName Contract = "Contract" | |
| </code></pre> | |
| </section> | |
| <section id="servant/svc-dsl"> | |
| <pre><code class="haskell"> | |
| type Api | |
| = "Contract" | |
| :> Capture "id" Int | |
| :> RoleFilter "Contract" "owner" '[43, 265] | |
| :> Get '[JSON] (Obj Contract) | |
| type Api | |
| = MkFilter Contract | |
| (RoleFilter C.Owner '[Role1, Role2]) | |
| </code></pre> | |
| </section> | |
| <section id="servant/svc-dsl-fn"> | |
| <pre><code class="haskell"> | |
| type family MkFilter | |
| (f :: Symbol) | |
| (m :: Symbol -> *) | |
| (filter :: *) | |
| where | |
| MkFilter f m (RoleFilter (own :: m g) rs) | |
| = TableName m | |
| :> Capture | |
| (FieldName (TableId m)) | |
| (FieldType (TableId m)) | |
| :> RoleFilter' (TableName m) g rs | |
| :> Get '[JSON] (Obj m) | |
| </code></pre> | |
| </section> | |
| <section id="hard"> | |
| <h1>Termination</h1> | |
| <h1>Equality</h1> | |
| <h1>Consistency</h1> | |
| </section> | |
| <section id="theory/refs"> | |
| <ul> | |
| <li> | |
| <a href="https://www.cis.upenn.edu/~eir/papers/2013/fckinds/fckinds.pdf">System FC with Explicit Kind Equality</a>, 2013 | |
| </li> | |
| <li> | |
| <a | |
| href="https://github.com/goldfirere/thesis/blob/master/built/proposal.pdf">Dependent Types in Haskell</a>, draft | |
| </li> | |
| <li> | |
| <a href="http://adam.gundry.co.uk/pub/thesis/">Type Inference, Haskell | |
| and Dependent Types</a>, 2013 | |
| </li> | |
| </ul> | |
| </section> | |
| <section id="steph"> | |
| <img src="http://www.cis.upenn.edu/~sweirich/images/steph-2012.jpg"/> | |
| <p>Stephanie Weirich<p> | |
| </section> | |
| <section id="rae"> | |
| <img src="https://www.cis.upenn.edu/~eir/rae.jpg"/> | |
| <p>Richard A. Eisenberg<p> | |
| </section> | |
| <section id="martin"> | |
| <img src="http://www.ae-info.org/attach/User/Martin-L%C3%B6f_Per/Per_Martin-Lof_big.jpg"/> | |
| <p>Per Martin-Löf, <a href="http://www.csie.ntu.edu.tw/~b94087/ITT.pdf">Intuitionistic type theory (1984)</a></p> | |
| </section> | |
| <section id="theend"> | |
| <div class="logo"> | |
| <span>F</span> | |
| <span>O</span> | |
| <span>R</span> | |
| <span>M</span> | |
| <span class="flipA">A</span> | |
| <span>L</span> | |
| <span> </span> | |
| <span>M</span> | |
| <span class="flipE">E</span> | |
| <span>T</span> | |
| <span>H</span> | |
| <span>O</span> | |
| <span>D</span> | |
| <span>S</span> | |
| </div> | |
| </section> | |
| <script> | |
| var edit = false; | |
| var sections = [].slice.call(document.getElementsByTagName('section')); | |
| sections.forEach(function(s) { | |
| s.onclick = function() { edit = s.contentEditable = true; }; | |
| s.onblur = function() { edit = s.contentEditable = false; }; | |
| }); | |
| var dict = {}; | |
| var root = {prev: null}; | |
| var current = root; | |
| sections.forEach(function(s) { | |
| current.hash = '#' + s.id; | |
| current.elem = s; | |
| dict[current.hash] = current; | |
| current = current.next = {prev: current}; | |
| }); | |
| current.prev.next = null; | |
| function hashchange() { | |
| current = dict[window.location.hash] || root; | |
| } | |
| window.addEventListener('hashchange', hashchange, false); | |
| hashchange(); | |
| function keydown(e) { | |
| switch(e.keyCode) { | |
| case 27: /* Esc */ | |
| edit = current.elem.contentEditable = false; | |
| break; | |
| case 37: /* Left */ break; | |
| case 38: /* Up */ | |
| if(!edit && current.prev) { | |
| window.location.hash = current.prev.hash; | |
| e.preventDefault(); | |
| } | |
| break; | |
| case 39: /* Right */ break; | |
| case 40: /* Down */ | |
| if(!edit && current.next) { | |
| window.location.hash = current.next.hash; | |
| e.preventDefault(); | |
| } | |
| break; | |
| } | |
| } | |
| window.addEventListener('keydown', keydown, false); | |
| hljs.initHighlighting(); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment