This repository was archived by the owner on Feb 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathMain.purs
135 lines (124 loc) · 4.65 KB
/
Main.purs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
module Test.Main where
import Prelude
import Control.Comonad.Cofree (Cofree, buildCofree)
import Control.Comonad.Store (StoreT, store)
import Control.Comonad.Traced (TracedT, traced)
import Control.Monad.Free.Class (wrapFree)
import Control.Monad.State (modify)
import Control.Monad.Writer (tell)
import Data.Functor.Pairing.Co (Co, co)
import Data.Identity (Identity)
import Data.Lazy (Lazy, defer, force)
import Data.Maybe (fromJust)
import Data.Monoid.Additive (Additive(..))
import Data.Tuple (Tuple(..))
import Effect (Effect)
import Partial.Unsafe (unsafePartial)
import React (ReactElement, unsafeCreateLeafElement)
import React.DOM as D
import React.DOM.Props as P
import React.Explore (Component, UI, explore)
import React.Explore.List as List
import React.Explore.Sum as Sum
import ReactDOM (render)
import Web.HTML.HTMLDocument (toNonElementParentNode)
import Web.DOM.NonElementParentNode (getElementById)
import Web.HTML (window)
import Web.HTML.Window (document)
-- | A counter component implemented using the `Store` comonad.
storeExample :: Component (StoreT Int Identity)
storeExample = store render 0 where
render :: Int -> UI (Co (StoreT Int Identity) Unit)
render count send =
D.div' [ D.p' [ D.text ("State: " <> show count) ]
, D.button [ P.onClick \_ ->
send (void (modify (add 1)))
]
[ D.text "Increment"
]
, D.button [ P.onClick \_ ->
send (void (modify (_ `sub` 1)))
]
[ D.text "Decrement"
]
]
-- | A counter component implemented using the `Traced` comonad.
tracedExample :: Component (TracedT (Additive Int) Identity)
tracedExample = traced render where
render :: Additive Int -> UI (Co (TracedT (Additive Int) Identity) Unit)
render (Additive count) send =
D.div' [ D.p' [ D.text ("State: " <> show count) ]
, D.button [ P.onClick \_ ->
send (tell (Additive 1))
]
[ D.text "+ 1"
]
, D.button [ P.onClick \_ ->
send (tell (Additive 10))
]
[ D.text "+ 10"
]
, D.button [ P.onClick \_ ->
send (tell (Additive 100))
]
[ D.text "+ 100"
]
]
-- | A counter component implemented using a `Cofree` comonad.
cofreeExample :: Component (Cofree Lazy)
cofreeExample = buildCofree step 0 where
moveRight :: Co Lazy Unit
moveRight = co \a -> force a unit
step :: Int -> Tuple (UI (Co (Cofree Lazy) Unit)) (Lazy Int)
step count = Tuple ui (defer \_ -> add count 1) where
ui :: UI (Co (Cofree Lazy) Unit)
ui send =
D.div' [ D.p' [ D.text ("State: " <> show count) ]
, D.button [ P.onClick \_ ->
send (wrapFree (moveRight $> pure unit))
]
[ D.text "Increment"
]
]
main :: Effect Unit
main = void (elm' >>= render ui) where
together = map addControls
(stores `Sum.combine` tracedExample `Sum.combine` cofreeExample)
addControls render send =
D.div' [ D.p' [ D.a [ P.onClick \_ -> send (Sum.moveLeft *> Sum.liftLeft Sum.moveLeft)
, P.href "#"
]
[ D.text "Stores example"
]
, D.text " — "
, D.a [ P.onClick \_ -> send (Sum.moveLeft *> Sum.liftLeft Sum.moveRight)
, P.href "#"
]
[ D.text "Traced example"
]
, D.text " — "
, D.a [ P.onClick \_ -> send Sum.moveRight
, P.href "#"
]
[ D.text "Cofree example"
]
]
, render send
]
stores = map withButton (List.listOf D.div' storeExample) where
withButton render send =
D.div' [ D.p' [ D.a [ P.onClick \_ -> send List.push
, P.href "#"
]
[ D.text "Add Store"
]
]
, render send
]
ui :: ReactElement
ui = D.div' [ unsafeCreateLeafElement (explore together) {} ]
elm' = do
win <- window
doc <- document win
elm <- getElementById "example" (toNonElementParentNode doc)
pure $ unsafePartial fromJust elm