0 | module Web.MVC.Controller
3 | import Data.List.Quantifiers.Extra
5 | import Text.HTML.DomID
7 | import public Control.Monad.State
8 | import public Web.MVC.Cmd
16 | export infixr 4 <$$>
25 | 0 Prog : (e,s,t : Type) -> Type
26 | Prog e s t = e -> State s t
29 | 0 Controller : (e,s : Type) -> Type
30 | Controller e s = Prog e s (Cmd e)
33 | (<$$>) : (x -> y) -> State s (Cmd x) -> State s (Cmd y)
37 | map2 : (x -> y) -> State s (Cmd x) -> State s (Cmd y)
41 | Semigroup (State s $
Cmd e) where x <+> y = [| x <+> y |]
44 | Monoid (State s $
Cmd e) where neutral = pure neutral
49 | direct : Monoid t => Prog e e t
50 | direct v = put v $> neutral
54 | directM : Monoid t => Prog e (Maybe e) t
55 | directM v = put (Just v) $> neutral
60 | displayEv : (s -> Cmd t) -> Prog s s (Cmd t)
61 | displayEv disp v = put v $> disp v
66 | updateDisp : (e -> s -> s) -> (e -> s -> Cmd t) -> Prog e s (Cmd t)
67 | updateDisp f g ev = modify (f ev) >> map (g ev) get
70 | data Progs : (evs : List Type) -> (sts : List Type) -> Type where
72 | (::) : Prog e s (Cmd e) -> Progs es ss -> Progs (e::es) (s::ss)
78 | progs : Progs es ss -> Controller (HSum es) (HList ss)
79 | progs [] ev = absurd ev
80 | progs (c::cs) (Here x) = Here <$$> stL allHead (c x)
81 | progs (c::cs) (There x) = There <$$> stL allTail (progs cs x)
83 | export covering %inline
84 | run : Prog e s (Cmd e) -> (initEv : e) -> (initST : s) -> IO ()
85 | run f = runController (\ev,st => runState st (f ev)) (putStrLn . dispErr)
113 | record Editor (i,st,ev,new : Type) where
116 | ctrl : i -> Controller ev st
119 | view : i -> st -> Node ev
124 | init : i -> st -> Cmd ev
129 | stToNew : st -> Either String new
132 | toState : Maybe new -> st
136 | newIso : Iso' n1 n2 -> Editor i st ev n1 -> Editor i st ev n2
137 | newIso i = {stToNew $= (map i.get_ .), toState $= (. map i.reverseGet)}
141 | noInit : i -> s -> Cmd e
142 | noInit _ _ = neutral
147 | toNewM : Editor i st ev new -> Maybe st -> Maybe new
148 | toNewM ed = (>>= eitherToMaybe . ed.stToNew)
152 | newP : Prism' t s -> Editor i st ev s -> Editor i st ev t
154 | { stToNew := map p.reverseGet . ed.stToNew
155 | , toState := \x => ed.toState $
x >>= first p
160 | dummy : n -> Editor i () Void n
162 | E (\_,_ => neutral) (\_,_ => Empty) (\_,_ => neutral) (\_ => Right v) (\_ => ())
169 | elemChildren : Cast t DomID => t -> List (Node e) -> Cmd e
170 | elemChildren = children . elemRef
173 | elemChild : Cast t DomID => t -> Node e -> Cmd e
174 | elemChild = child . elemRef
177 | elemAppend : Cast t DomID => t -> Node e -> Cmd e
178 | elemAppend = append . elemRef
181 | elemPrepend : Cast t DomID => t -> Node e -> Cmd e
182 | elemPrepend = prepend . elemRef
185 | clearElem : Cast t DomID => t -> Cmd e
186 | clearElem v = elemChildren v []
189 | removeElem : Cast t DomID => t -> Cmd e
190 | removeElem = remove . elemRef
193 | replaceElem : Cast t DomID => t -> Node e -> Cmd e
194 | replaceElem = replace . elemRef
197 | btnAttr : Cast t DomID => t -> Attribute Tag.Button e -> Cmd e
198 | btnAttr v = attr (btnRef v)