-
Notifications
You must be signed in to change notification settings - Fork 30
/
Main.hs
87 lines (65 loc) · 2.58 KB
/
Main.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
80
81
82
83
84
85
86
87
module Main where
import Control.Applicative
import Control.DysFRP
import Graphics.Gloss.Interface.IO.Game hiding (Event)
import Buttons
import GlossInterface
-- Utilities
if_then_else :: Bool -> a -> a -> a
if_then_else True t _ = t
if_then_else False _ f = f
replaceWith :: a -> Event b -> Event a
replaceWith = fmap . const
filterEq :: Eq a => a -> Event a -> Event ()
filterEq x = replaceWith () . filterE (== x)
eachE :: Event () -> a -> Event a
eachE = flip replaceWith
-- FRP network
mainDysFRP :: Event Float
-> Event InputEvent
-> BehaviorGen Picture
mainDysFRP _ glossEvent = do
-- Part 1: static version
--
mode0 <- accumB True $ constE not toggle0
mode5 <- accumB True $ constE not toggle5
mode10 <- accumB True $ constE not toggle10
count0 <- accumB 0 $ constE (+1) click0 `appendE` constE (const 0) toggle0
count5 <- accumB 0 $ whenE mode5 $ constE (+1) click5
count10 <- accumB 0 $ constE (+1) click10
let output0 = if_then_else <$> mode0 <*> count0 <*> minus1
let output5 = if_then_else <$> mode5 <*> count5 <*> minus1
let output10 = if_then_else <$> mode10 <*> count10 <*> minus1
let counterB click = accumB 0 $ constE (+1) click
-- Part 2: dynamic version
-- scenario 0: new counter created each time
initCount0 <- counterB click0
dynamicCount0 <- switchB initCount0 $
genToE (\b -> if b then -1 else counterB click0) $
snapshotE mode0 $ toggle0
-- scenario 10: re-using the first counter
initCount10 <- counterB click10
dynamicCount10 <- switchB initCount10 $
fmap (\b -> if b then -1 else initCount10) $
snapshotE mode10 $ toggle10
return $ renderButtons <$> output0 <*> (Just <$> dynamicCount0)
<*> output5 <*> pure Nothing
<*> output10 <*> (Just <$> dynamicCount10)
where
minus1 = constB (-1)
-- Input
click0, click5, click10 :: Event ()
click0 = filterEq (Just Click) $ filter0 <$> glossEvent
click5 = filterEq (Just Click) $ filter5 <$> glossEvent
click10 = filterEq (Just Click) $ filter10 <$> glossEvent
toggle0, toggle5, toggle10 :: Event ()
toggle0 = filterEq (Just Toggle) $ filter0 <$> glossEvent
toggle5 = filterEq (Just Toggle) $ filter5 <$> glossEvent
toggle10 = filterEq (Just Toggle) $ filter10 <$> glossEvent
-- Gloss event loop
main :: IO ()
main = playDysFRP
(InWindow "DysFRP Example" (320, 240) (800, 200))
white
30
mainDysFRP