I discuss Haste, which compiles Haskell code to Javascript to be run on the browser. I then cover Tagless Final Style, which is a technique for creating flexible and extensible DSLs.
3. + Full Haskell 2010 Support
(Proper Numbers, Lazy, Pure, Type Classes, …)
+ Nearly all GHC extensions
+ Supports large amount of Hackage
+ Cabal-style build
+ Compact output (~2k hello world)
+ Fast
+ Javascript FFI
+ Browser API
4. - No Template Haskell
- No GHCi
- No forkIO
- No Weak Pointers
5. Elm
Haskell-inspired. Strict. Structural typing and FRP.
Purescript
Haskell-inspired. Strict. Structural typing and Effect typing.
Fay
Haskell subset. Lazy. Small & Fast code. No type classes.
GHCJS
Full GHC. Big runtime with GC, Thread scheduler, etc
27. Initial Style
data Html = Div [Attr] [Html]
| Button [Attr] [Html]
| Text String
client :: Html → JSPtr
client (Div attrs children) = …
client (Button attrs children) = …
client (Text str) = …
server :: Html → String
server (Div attrs children) = …
server (Button attrs children) = …
server (Text str) = …
i
i
28. server :: Html → String
server (Div attrs children) =
“<div” ++ show attrs ++ “>”
++ concatMap server children
++ “</div>”
server (Button attrs children) =
“<button” ++ show attrs ++ “>”
++ concatMap server children
++ “</button>”
server (Text str) = str
30. class Html i where
div :: [Attr] → [ i ] → i
button :: [Attr] → [ i ] → i
text :: String → i
Final Style
31. Final Style
class Html i where
div :: [Attr] → [i] → i
button :: [Attr] → [i] → i
text :: String → i
-- Initial Style
data Html =
Div [Attr] [Html]
| Button [Attr] [Html]
| Text String
32. Final Style
class Html i where
div :: [Attr] → [i] → i
button :: [Attr] → [i] → i
text :: String → i
-- Initial Style (GADT)
data Html where
Div :: [Attr] → [Html] → Html
Button :: [Attr] → [Html] → Html
Text :: String → Html
33. Final Style
class Html i where
div :: [Attr] → [i] → i
button :: [Attr] → [i] → i
text :: String → i
instance Html String where
div attrs children = …
button attrs children = …
text str = …
instance Html JSPtr where
div attrs children = …
button attrs children = …
text str = …
i
i
35. instance Html String where
div attrs children =
“<div” ++ show attrs ++ “>”
++ concatMap srv children
++ “</div>”
button attrs children =
“<button” ++ show attrs ++ “>”
++ concatMap srv children
++ “</button>”
text str = str
36. instance Html String where
-- div :: [Attr] → [i] → i
div attrs children =
“<div” ++ show attrs ++ “>”
++ concatMap ??? children
++ “</div>”
-- button :: [Attr] → [i] → i
button attrs children =
“<button” ++ show attrs ++ “>”
++ concatMap ??? children
++ “</button>”
-- text:: String → i
text str = str
37. instance Html String where
-- div :: [Attr] → [i] → i
div attrs children =
“<div” ++ show attrs ++ “>”
++ concatMap id children
++ “</div>”
-- button :: [Attr] → [i] → i
button attrs children =
“<button” ++ show attrs ++ “>”
++ concatMap id children
++ “</button>”
-- text:: String → i
text str = str
38. instance Html String where
-- div :: [Attr] → [i] → i
div attrs children =
“<div” ++ show attrs ++ “>”
++ concat children
++ “</div>”
-- button :: [Attr] → [i] → i
button attrs children =
“<button” ++ show attrs ++ “>”
++ concat children
++ “</button>”
-- text:: String → i
text str = str
39. -- Initial Style
i :: Html
i = Div [] [(Button [] [Text “clickMe”])]
iOut :: String
iOut = server i
-- Final Style
f :: (Html i) => i
f = div [] [(button [] [text “clickMe”])]
fOut = f :: String
40. class Math (i :: * ) where
lit :: Int → i
(+) :: i → i → i
(>) :: i → i → i
instance Math Int where …
instance Math String where …
i
i
41. class Math (i :: *→*) where
lit :: Int → i Int
(+) :: i Int → i Int → i Int
(>) :: i Int → i Int → i Bool
42. class Math (i :: *→*) where
lit :: Int → i Int
(+) :: i Int → i Int → i Int
(>) :: i Int → i Int → i Bool
newtype Eval a = Eval {eval :: a}
instance Math Eval where …
newtype Pretty a = Pretty {pp :: String}
instance Math Pretty where …
a = (lit 1) > ((lit 2) + (lit 3))
e = eval a -- False
p = pp a -- “(1 > (2 + 3))”
i
i
43. class Html i where
div :: [Attr] → [i] → i
button :: [Attr] → [i] → i
text :: String → i
instance SafariHtml String where
webkitElt attrs children) = …
instance SafariHtml JSPtr where
webkitElt attrs children) = …
class SafariHtml i where
webkitElt :: [Attr] → [i] → i
Language Extensibility
i
i
44. f :: (Html i, SafariHtml i) => i
f = div [] [(webkitElt [] [text “clickMe”])]
fOut = f :: String
Language Extensibility
45. div :: (Attr a, Html i) => [a] → [i] → i
-- div [idName “mydiv”] []
button :: (Attr a, Html i) => [a] → [i] → i
-- button [idName “mybtn”, disabled True] []
class Attr a where
idName :: String → a
disabled :: Bool → a
instance Attr DivAttr where
idName s = …
disabled b = … instance Attr ButtonAttr where
idName s = …
disabled b = …
newtype ButtonAttr
newtype DivAttr
i
i
46. div :: (Html i) => [DivAttr] → [i] → i
-- div [idName “mydiv”] []
button :: (Html i) => [ButtonAttr] → [i] → i
-- button [idName “mybtn”, disabled True] []
class IdA a where
idName :: String → a
class DisabledA a where
disabled :: Bool → a
instance IdA ButtonAttr where
idName s = …
instance DisabledA ButtonAttr where
disabled b = …
newtype ButtonAttrinstance IdA DivAttr where
idName s = …
newtype DivAttr
i
i
i
47. type src form
<img>
instance
SrcA ImgAttr
<input>
instance
TypeA InputAttr
instance
SrcA InputAttr
instance
FormA InputAttr
<button
>
instance
TypeA ButtonAttr
instance
FormA ButtonAttr
<label>
instance
FormA LabelAttr
i
i
i
i i
i
i
48. Typed Tagless Final Course Notes
okmij.org/ftp/tagless-final/course/lecture.pdf
haste-lang.org
“Haskell in the Browser With Haste” Lars Kuhtz
alephcloud.github.io/bayhac2014/slides
facebook.github.io/react
github.com/takeoutweight @takeoutweight