Skip to content

Instantly share code, notes, and snippets.

@TheSeamau5
Created August 28, 2015 19:48
Embed
What would you like to do?
import Signal exposing (Address)
import Html exposing (Html, div, button, text, span)
import Html.Events exposing (onClick)
type alias Init options state effect = options -> (state, List effect)
type alias Update action state effect = action -> state -> (state, List effect)
type alias View state view = state -> view
type alias Component options action state effect view =
{ init : Init options state effect
, update : Update action state effect
, view : View state view
}
type alias HtmlComponent options action state effect =
Component options action state effect (Address action -> Html)
---------------
-- COUNTER ----
---------------
type Action
= Increment
| Decrement
counter : HtmlComponent Void Action Int Never
counter =
let
init = 0
update action state =
case action of
Increment ->
state + 1
Decrement ->
state - 1
view state address =
div
[]
[ button
[ onClick address Increment ]
[ text "+" ]
, button
[ onClick address Decrement ]
[ text "-" ]
, span
[]
[ text (toString state) ]
]
in
sealed
{ init = init
, update = update
, view = view
}
main =
run Void counter
|> .views
---------------
sealed : { init : state
, update : action -> state -> state
, view : state -> view
}
-> Component Void action state Never view
sealed { init , update , view } =
{ init = always (init, [])
, update = (\a s -> (update a s, []))
, view = view
}
simple : { init : state
, view : state -> view
}
-> Component Void action state Never view
simple {init, view} =
{ init = always (init, [])
, update = (\_ s -> (s, []))
, view = view
}
type alias Output action state effect =
{ actions : Signal (Maybe action)
, states : Signal state
, effects : Signal (List effect)
, views : Signal Html
}
run : options
-> HtmlComponent options action state effect
-> Output action state effect
run options component =
let
appMailbox =
Signal.mailbox Nothing
actions =
appMailbox.signal
address =
Signal.forwardTo appMailbox.address Just
update maybeAction (state, effects) =
case maybeAction of
Nothing ->
(state, effects)
Just action ->
component.update action state
view =
flip component.view address
initial =
component.init options
transitions =
Signal.foldp update initial actions
states =
Signal.map fst transitions
effects =
Signal.map snd transitions
views =
Signal.map view states
in
{ actions = actions
, states = states
, effects = effects
, views = views
}
type Never = Never Never
type Void = Void
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment