Skip to content

Instantly share code, notes, and snippets.

@yogsototh
Created May 27, 2015 20:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yogsototh/691eafc98140e1a0316d to your computer and use it in GitHub Desktop.
Save yogsototh/691eafc98140e1a0316d to your computer and use it in GitHub Desktop.
import Timer
import Signal exposing (Address,Mailbox,mailbox)
import Html exposing (div, button, text, Html)
import Html.Events exposing (onClick)
import Task exposing (Task,andThen)
import Http
import Time exposing (every,second)
main : Signal Html
main = start app
type alias App model action taskAction taskErr =
{ model : model
, view : Address action -> model -> Html
, update : action -> model -> model
, externalSignals : Signal action
, tasksBox : Mailbox (Maybe taskAction)
, internalBox : Mailbox (Maybe action)
, handleTasks : taskAction -> Task taskErr action
}
type alias Error = Http.Error
app : App Model Action TaskAction Error
app = { model = model
, view = view
, update = update
, externalSignals = initSignals
, tasksBox = mailbox Nothing
, internalBox = mailbox Nothing
, handleTasks = handleTasks
}
port taskRunner : Signal (Task Error ())
port taskRunner = Signal.map runTask app.tasksBox.signal
runTask : Maybe TaskAction -> Task Error ()
runTask t = case t of
(Just taskAction) -> app.handleTasks taskAction `andThen` report app.internalBox
Nothing -> Task.fail Http.Timeout
type TaskAction = TCall
handleTasks : TaskAction -> Task x Action
handleTasks taskAction = case taskAction of
TCall -> Task.succeed Call
report : Mailbox (Maybe a) -> a -> Task x ()
report box act = Signal.send box.address (Just act)
initSignals : Signal Action
initSignals = Signal.map (\_ -> TimePassed) (every second)
start : App model action taskActions taskErr -> Signal Html
start app =
let
actions = Signal.mailbox Nothing
address = Signal.forwardTo actions.address Just
model = Signal.foldp (\(Just action) model -> app.update action model)
app.model
(Signal.merge app.internalBox.signal
(Signal.merge actions.signal
(Signal.map Just app.externalSignals)))
in
Signal.map (app.view address) model
-- MODEL
type alias Model = Int
model : Model
model = 0
-- UPDATE
type Action = TimePassed
| Call
update : Action -> Model -> Model
update action model =
case action of
TimePassed -> model + 1
-- VIEW
view : Address Action -> Model -> Html
view address model =
div []
[ text (toString model)
, button [ onClick address TimePassed ] [ text "+" ]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment