Skip to content

Instantly share code, notes, and snippets.

@TheSeamau5
Created August 28, 2015 19:48
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/971f3464baa21189dd78 to your computer and use it in GitHub Desktop.
Save TheSeamau5/971f3464baa21189dd78 to your computer and use it in GitHub Desktop.
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