Doug Beardsley
Takt
Two production reflex apps
Misc small projects
Correct type signature
foo :: MonadWidget t m => Dynamic t Foo -> m (Event t ())
In this presentation
foo :: Dynamic Foo -> m (Event ())
When to use each one?
dynText :: Dynamic Text -> m ()
?never :: Event a
hold :: a -> Event a -> m (Behavior a)
tag :: Behavior a -> Event b -> Event a
attach :: Behavior a -> Event b -> Event (a,b)
attachWith :: (a -> b -> c) -> Behavior a -> Event b -> Event c
switch :: Behavior (Event a) -> Event a
Accessors
current :: Dynamic a -> Behavior a
updated :: Dynamic a -> Event a
Construction
constDyn :: a -> Dynamic a
holdDyn :: a -> Event a -> m (Dynamic a)
foldDyn :: (a -> b -> b) -> b -> Event a -> m (Dynamic b)
tagDyn :: Dynamic a -> Event b -> Event a
attachDyn :: Dynamic a -> Event b -> Event (a,b)
attachDynWith :: (a -> b -> c) -> Dynamic a -> Event b -> Event c
Functor | Applicative | Monad | |
---|---|---|---|
Event | X | ||
Behavior | X | X | X |
Dynamic | X | X | X |
T.pack . show <$> anEvent
() <$ anEvent
hold :: a -> Event a -> m (Behavior a)
holdDyn :: a -> Event a -> m (Dynamic a)
s/a/Maybe a/
maybe
, fromMaybe
, etcfmapMaybe :: (a -> Maybe b) -> Event a -> Event b
fmapMaybe id :: Event (Maybe a) -> Event a
How to write?
textErr :: Either Text Text -> m ()
textErr :: Either Text Text -> m ()
textErr (Left err) = elClass "span" "red-text" $ text err
textErr (Right t) = text t
Outer | Inner | Collapsing Function |
---|---|---|
Dynamic | Dynamic | |
Dynamic | Behavior | |
Dynamic | Event | |
Behavior | Dynamic | |
Behavior | Behavior | |
Behavior | Event | |
Event | Dynamic | |
Event | Behavior | |
Event | Event |
Outer | Inner | Collapsing Function |
---|---|---|
Dynamic | Dynamic | join |
Dynamic | Behavior | join . current |
Dynamic | Event | switch . current, switchPromptlyDyn |
Behavior | Dynamic | join . fmap current |
Behavior | Behavior | join |
Behavior | Event | switch |
Event | Dynamic | join . holdDyn iv |
Event | Behavior | join . hold iv |
Event | Event | switch . hold iv, switchPromptly, switchPromptOnly |
"Definitive" widget
widget :: a -> Event a -> m (Dynamic a)
View Widgets
widget :: Dynamic a -> m (Event a)
current :: Dynamic a -> Behavior a
updated :: Dynamic a -> Event a
updated
gets the new value from the firing eventcurrent
gets the value from the previous frameuniqDyn
supresses the firing if nothing changedtweetWidget = do
click <- button "Send Tweet"
ta <- textArea $ def & setValue .~ ("" <$ click)
...
vs
tweetWidget = do
rec ta <- textArea $ def & setValue .~ ("" <$ click)
click <- button "Send Tweet"
...
loopWidget = do
rec click <- button "Add"
val <- formWidget a
let a = leftmost [42 <$ click, updated val]
rec
block.loopWidget = do
rec click <- button "Add"
val <- formWidget a
let a = leftmost [42 <$ click, updated val]
vs
loopWidget = do
click <- button "Add"
rec val <- formWidget a
let a = leftmost [42 <$ click, updated val]
rec
block, so keep them as small as possibleFor
m ()
Replace with
return ()
For
m (Event a)
Replace with
return never
For
m (Dynamic (Maybe a))
Replace with
return (constDyn Nothing)
rec
block, so keep them as small as possibleval <- case ty of
InputChar -> charWidget
InputString -> stringWidget
InputInt -> intWidget
InputDouble -> doubleWidget
InputDate -> dateWidget
InputTime -> timeWidget
InputDateTime -> dateTimeWidget
InputEnum -> enumWidget
val <- case ty of
-- InputChar -> charWidget
-- InputString -> stringWidget
-- InputInt -> intWidget
-- InputDouble -> doubleWidget
InputDate -> dateWidget
InputTime -> timeWidget
InputDateTime -> dateTimeWidget
InputEnum -> enumWidget
val <- case ty of
InputChar -> charWidget
InputString -> stringWidget
InputInt -> intWidget
InputDouble -> doubleWidget
-- InputDate -> dateWidget
-- InputTime -> timeWidget
-- InputDateTime -> dateTimeWidget
-- InputEnum -> enumWidget
val <- case ty of
-- InputChar -> charWidget
-- InputString -> stringWidget
-- InputInt -> intWidget
-- InputDouble -> doubleWidget
-- InputDate -> dateWidget
-- InputTime -> timeWidget
InputDateTime -> dateTimeWidget
InputEnum -> enumWidget
val <- case ty of
-- InputChar -> charWidget
-- InputString -> stringWidget
-- InputInt -> intWidget
-- InputDouble -> doubleWidget
-- InputDate -> dateWidget
-- InputTime -> timeWidget
-- InputDateTime -> dateTimeWidget
InputEnum -> enumWidget
current
Two examples I've actually encountered
attachPromptlyDynWith func d e
attachWith func (current d) e
and
tagPromptlyDyn d e
tag (current d) e
current
value
http://mightybyte.net/real-world-reflex/index.html
doug@takt.com
Looking for a job? Takt is hiring!