@@ -40,20 +40,26 @@ pure : (a -> b) -> Automaton a b
40pure f = Step (\x -> (pure f, f x))
40pure f = Step (\x -> (pure f, f x))
42-- Create an automaton with state. Requires an initial state and a step
42-- Create an automaton with state. Requires an initial state and a step
43−-- function to step the state forward.
43+-- function to step the state forward. For example, an automaton that counted
44+-- how many steps it has taken would look like this:
46+-- count = state 0 (\\_ c -> c+1)
48+-- It is a stateful automaton. The initial state is zero, and the step function
49+-- increments the state on every step.
44−init : b -> (a -> b -> b) -> Automaton a b
50+state : b -> (a -> b -> b) -> Automaton a b
45−init s f = Step (\x -> let s' = f x s
51+state s f = Step (\x -> let s' = f x s
46− in (init s' f, s'))
52+ in (state s' f, s'))
48-- Create an automaton with hidden state. Requires an initial state and a
54-- Create an automaton with hidden state. Requires an initial state and a
49-- step function to step the state forward and produce an output.
55-- step function to step the state forward and produce an output.
50−init' : s -> (a -> s -> (s,b)) -> Automaton a b
56+hiddenState : s -> (a -> s -> (s,b)) -> Automaton a b
51−init' s f = Step (\x -> let (s',out) = f x s
57+hiddenState s f = Step (\x -> let (s',out) = f x s
52− in (init' s' f, out))
58+ in (hiddenState s' f, out))
54-- Count the number of steps taken.
60-- Count the number of steps taken.
55count : Automaton a Int
61count : Automaton a Int
56−count = init 0 (\_ c -> c + 1)
62+count = state 0 (\_ c -> c + 1)
58type Queue t = ([t],[t])
64type Queue t = ([t],[t])
59empty = ([],[])
65empty = ([],[])
@@ -64,7 +70,7 @@ dequeue q = case q of
64 (en,hd::tl) -> Just (hd, (en,tl))
70 (en,hd::tl) -> Just (hd, (en,tl))
66-- Computes the running average of the last `n` inputs.
72-- Computes the running average of the last `n` inputs.
67−average : Int -> Automaton (Number a) (Number a)
73+average : Int -> Automaton Float Float
68average k =
74average k =
69 let step n (ns,len,sum) =
75 let step n (ns,len,sum) =
70 if len == k then stepFull n (ns,len,sum)
76 if len == k then stepFull n (ns,len,sum)
@@ -74,30 +80,8 @@ average k =
74 Nothing -> ((ns,len,sum), 0)
80 Nothing -> ((ns,len,sum), 0)
75 Just (m,ns') -> let sum' = sum + n - m
81 Just (m,ns') -> let sum' = sum + n - m
76 in ((enqueue n ns', len, sum'), sum' / len)
82 in ((enqueue n ns', len, sum'), sum' / len)
77− in init' (empty,0,0) step
83+ in hiddenState (empty,0,0) step
79−{-- TODO(evancz): move this code to the Form library so people can find it.
81−data DragState = Listen | Ignore | DragFrom (Int,Int)
83−vecSub (x1,y1) (x2,y2) = (x1-x2,y1-y2)
85−stepDrag (press,pos) (ds,form) =
86− let wrap ds' = (form, (ds',form)) in
88− Listen -> wrap (if | not press -> Listen
89− | pos `isWithin` form -> DragFrom pos
90− | otherwise -> Ignore)
91− Ignore -> wrap (if press then Ignore else Listen)
93− if press then (uncurry move (vecSub pos p0) form, (DragFrom p0, form))
94− else (let form' = uncurry move (vecSub pos p0) form in
95− (form', (Listen,form')))
97−-- Create a draggable form that can be dynamically created and added to a scene.
98−draggable : Form -> Automaton (Bool,(Int,Int)) Form
99−draggable form = init' (Listen,form) stepDrag
102{-- TODO(evancz): See the following papers for ideas on how to make this
86{-- TODO(evancz): See the following papers for ideas on how to make this
103library faster and better:
87library faster and better: