Skip to content

Instantly share code, notes, and snippets.

@TheSeamau5
Last active August 29, 2015 14:21
Show Gist options
  • Save TheSeamau5/3ccbb41a05f69a89b7ea to your computer and use it in GitHub Desktop.
Save TheSeamau5/3ccbb41a05f69a89b7ea to your computer and use it in GitHub Desktop.
import Signal exposing (Address, Mailbox, Signal, forwardTo)
import Html exposing (Html, div, ul, li)
import List
update : ID -> (state -> state) -> ContainerState state -> ContainerState state
update id f list =
case list of
[] -> []
(id', x) :: xs ->
if id == id'
then
(id', f x) :: xs
else
(id', x) :: update id f xs
get id list =
case list of
[] -> Nothing
(id', x) :: xs ->
if id == id'
then
Just x
else
get id xs
nth : Int -> List a -> Maybe a
nth n list =
if n <= 0
then Nothing
else
case list of
[] -> Nothing
x :: xs ->
if n == 1
then
Just x
else
nth (n - 1) xs
type alias Component action state view =
{ initial : state
, view : Address action -> state -> view
, update : action -> state -> state
}
type alias ID = Int
component initial view update =
{ initial = initial
, view = view
, update = update
}
type ContainerAction action
= Child ID action
type alias ContainerState state
= List (ID, state)
container : List (Component action state Html) -> Component (ContainerAction action) (ContainerState state) Html
container components =
let
-- initial : ContainerState state
initial =
List.indexedMap (\id component -> (id, component.initial)) components
-- viewOne : Address (ContainerAction action) -> (ID, state) -> Component action state Html -> Html
viewOne address (id, state) component =
li
[]
[ component.view (forwardTo address (Child id)) state ]
-- view : Address (ContainerAction action) -> ContainerState state -> Html
view address state =
ul
[]
( List.map2 (viewOne address) state components )
-- update' : ContainerAction action -> ContainerState state -> ContainerState state
update' (Child id action) state =
case nth id components of
Nothing -> state
Just component ->
update id (component.update action) state
in
component initial view update'
text : Component String String Html
text =
let
initial = ""
view address state =
Html.text state
update action state =
action
in
component initial view update
comp =
container
[ text
, text
, text
]
play : Mailbox action -> Component action state Html -> Signal Html
play {address, signal} {initial, view, update} =
Signal.map (view address)
(Signal.foldp update initial signal)
mailbox = Signal.mailbox (Child 2 "h")
main = play mailbox comp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment