Skip to content

Instantly share code, notes, and snippets.

@TheSeamau5
Last active August 28, 2015 00:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheSeamau5/ec624266e9a10ef12f4f to your computer and use it in GitHub Desktop.
Save TheSeamau5/ec624266e9a10ef12f4f to your computer and use it in GitHub Desktop.
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
@rgrempel
Copy link

I think you could change

  [ text (toString state) ]

to read

 [ text (toString update) ]

... then it would construct the view from the new state, rather than the old state.

@TheSeamau5
Copy link
Author

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