Last active
August 28, 2015 00:25
-
-
Save TheSeamau5/ec624266e9a10ef12f4f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Signal exposing (Address) | |
import Html exposing (Html, div, span, button, text) | |
import Html.Events exposing (onClick) | |
import Time | |
type alias Component action state effect view = | |
state -> (action -> (state, List effect), view) | |
---------- | |
-- EXAMPLE | |
---------- | |
type alias State = Int | |
type Action | |
= Increment | |
| Decrement | |
| NextFrame | |
counter : Component Action State Never (Address Action -> Html) | |
counter state = | |
let | |
update action = | |
case action of | |
Increment -> | |
(state + 1, []) | |
Decrement -> | |
(state - 1, []) | |
NextFrame -> | |
(state, []) | |
view address = | |
div | |
[] | |
[ button | |
[ onClick address Increment ] | |
[ text "+" ] | |
, button | |
[ onClick address Decrement ] | |
[ text "-" ] | |
, span | |
[] | |
[ text (toString state) ] | |
] | |
in | |
(update, view) | |
main = | |
runHtml counter 0 (Signal.sampleOn (Time.fps 60) (Signal.constant NextFrame)) | |
|> .views | |
---------- | |
type alias Output state effect view = | |
{ states : Signal state | |
, effects : Signal (List effect) | |
, views : Signal view | |
} | |
runHtml : Component action state effect (Address action -> Html) | |
-> state | |
-> Signal action | |
-> Output state effect Html | |
runHtml component state externalActions = | |
let | |
{address, signal} = | |
Signal.mailbox Nothing | |
componentAddress = | |
Signal.forwardTo address Just | |
{states, effects, views} = | |
externalActions | |
|> Signal.map Just | |
|> Signal.merge signal | |
|> run component state | |
in | |
{ states = states | |
, effects = effects | |
, views = Signal.map (\f -> f componentAddress) views | |
} | |
run : Component action state effect view | |
-> state | |
-> Signal (Maybe action) | |
-> Output state effect view | |
run component state actions = | |
let | |
makeTuple action state = | |
let | |
(performAction, view) = | |
component state | |
(nextState, effects) = | |
performAction action | |
in | |
(nextState, effects, view) | |
update maybeAction ((state, _, _) as transition) = | |
case maybeAction of | |
Nothing -> | |
transition | |
Just action -> | |
makeTuple action state | |
initialView = | |
snd (component state) | |
initialTuple = | |
(state, [], initialView) | |
outputs = | |
Signal.foldp update initialTuple actions | |
states = | |
Signal.map (\(a,_,_) -> a) outputs | |
effects = | |
Signal.map (\(_,b,_) -> b) outputs | |
views = | |
Signal.map (\(_,_,c) -> c) outputs | |
in | |
{ states = states | |
, effects = effects | |
, views = views | |
} | |
type Never = Never Never | |
update
is a function not a value
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I think you could change
to read
... then it would construct the view from the new state, rather than the old state.