google / google/codeworld

Consider Reader/Writer monad for reflex input and output

Open
#1,056 5 comments 0 reactions 0 assignees View on GitHub
enhancement time_wait
Dominant language
Haskell
Stars
1.3k
Forks
201
PR merge metrics
No merged PRs in 30d

Description

Here's an interesting idea for `reflexOf`:

class (..., t ~ ...) => CodeWorldReflex t m where
keyPress :: m (Event t Text)
keyRelease :: m (Event t Text)
...
draw :: Dynamic t Picture -> m ()

reflexOf :: CodeWorldReflex m => m () -> IO ()

This would replace the existing `ReactiveInput` type, so it saves some complexity as well as adding it. `draw` replaces the `Dynamic t Picture` return value in the existing API.

This parallels the way reflex-dom works, where a builder monad can emit pieces of output on the screen. Under the scenes, there's just an implied top-level `pictures` function that combines all the emitted pictures into one screen.

Here's why this is appealing:

main = reflexOf $ do
param1 <- gauge $ gaugeConfig {
gaugeLabel = "param1",
gaugeRange = (1, 10),
gaugeStart = 5,
gaugePosition = (0, -6)
}
param2 <- gauge $ gaugeConfig {
gaugeLabel = "param2",
gaugeRange = (1, 10),
gaugeStart = 5,
gaugePosition = (0, -6)
}
param3 <- gauge $ gaugeConfig {
gaugeLabel = "param3",
gaugeRange = (1, 10),
gaugeStart = 5,
gaugePosition = (0, -6)
}
emit (renderWith <$> param1 <*> param2 <*> param3)

gauge GaugeConfig{..} = do
click <- pointerPress
release <- pointerRelease
dragging <- holdDyn $ mergeWith (&&) [
True <$ ffilter inBounds click,
False <$ release
]
drag <- gateDyn dragging =<< updated pointerPosition
value <- holdDyn gaugeStart (toValue <$> drag)
emit $ drawGauge <$> value
return value
where inBounds (x, y) = ...
toValue (x, y) = ...
drawGauge val = ...

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.