-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathnested_dynamics.hs
79 lines (61 loc) · 2.33 KB
/
nested_dynamics.hs
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
-- A slightly contrived example just to demonstrate use of nested dynamics
-- This example also has a nested state machine,
-- By using foldDynM, we could use foldDyn inside of it.
--
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE LambdaCase #-}
import Reflex.Dom
import Data.Text as T
import Data.Monoid
-- A ScoreCard can either display some info/updates or the current score
data ScoreCard t =
Info (Dynamic t Text)
| Score (Dynamic t Int)
data GameEvent =
NewGame
| DoTurn Text Int -- Some info and points earned
main = mainWidget $ do
newGameEv <- button "New Game"
toggleCardEv <- button "Toggle Display"
m1 <- button "Do move 1"
m2 <- button "Do move 2"
m3 <- button "Do move 3"
m4 <- button "Do move 4"
let
-- gameEv :: (Reflex t) => Event t GameEvent
gameEv = leftmost [newGame, move1, move2, move3, move4]
newGame = NewGame <$ newGameEv
move1 = (DoTurn "Move 1" 1) <$ m1
move2 = (DoTurn "Move 2" 20) <$ m2
move3 = (DoTurn "Move 3" 10) <$ m3
move4 = (DoTurn "Move 4" 5) <$ m4
-- Capture the score, in a Dynamic independent of ScoreCard
-- This will maintain its value irrespective of the state of ScoreCard
scoreDyn <- do
let handleGameEvent (NewGame) _ = 0
handleGameEvent (DoTurn _ s) p = p + s
foldDyn handleGameEvent 0 gameEv
let
initCard = Score scoreDyn
eventHandler _ (Info _) = return (Score scoreDyn)
eventHandler _ (Score _) = do
let handleGameEvent (NewGame) _ = "New Game!"
handleGameEvent (DoTurn t _) "" = "You did " <> t
handleGameEvent (DoTurn t _) p = p <> ", " <> t
-- Internal state machine using foldDyn
-- Capture the info text in a Dynamic which is in the scope
-- of ScoreCard.
-- So this will be reset whenever you toggle the display of score card
textDyn <- foldDyn handleGameEvent "" gameEv
return (Info textDyn)
-- external state machine using foldDynM
-- Here the (ScoreCard t) itself contains a Dynamic value
-- scoreCardDyn :: Dynamic t (ScoreCard t)
scoreCardDyn <- foldDynM eventHandler initCard toggleCardEv
dyn (renderScoreCard <$> scoreCardDyn)
return ()
renderScoreCard sc =
el "div" $
case sc of
(Info t) -> text "Info: " >> dynText t
(Score s) -> text "Score: " >> dynText (T.pack <$> show <$> s)