elm 请转到此处:http://package.elm-lang.org/packages/z5h/time-app/

请转到此处:http://package.elm-lang.org/packages/z5h/time-app/

TimeApp.elm
module TimeApp ( start, Config, App ) where
{-| This module helps you start your application in a typical Elm workflow.
It assumes you are following [the Elm Architecture][arch] and using
[elm-effects][]. From there it will wire everything up for you!

**Be sure to [read the Elm Architecture tutorial][arch] to learn how this all
works!**

[arch]: https://github.com/evancz/elm-architecture-tutorial
[elm-effects]: http://package.elm-lang.org/packages/evancz/elm-effects/latest

# Start your Application
@docs start, Config, App

-}

import Html exposing (Html)
import Task
import Effects exposing (Effects, Never)
import Time exposing (Time)


{-| The configuration of an app follows the basic model / update / view pattern
that you see in every Elm program.

The `init` transaction will give you an initial model and create any tasks that
are needed on start up.

The `update` and `view` fields describe how to step the model and view the
model.

The `inputs` field is for any external signals you might need. If you need to
get values from JavaScript, they will come in through a port as a signal which
you can pipe into your app as one of the `inputs`.
-}
type alias Config model action =
    { init : (model, Effects action)
    , update : action -> Time -> model -> (model, Effects action)
    , view : Signal.Address action -> model -> Html
    , inputs : List (Signal.Signal action)
    }


{-| An `App` is made up of a couple signals:

  * `html` — a signal of `Html` representing the current visual
    representation of your app. This should be fed into `main`.

  * `model` — a signal representing the current model. Generally you
    will not need this one, but it is there just in case. You will know if you
    need this.

  * `tasks` — a signal of tasks that need to get run. Your app is going
    to be producing tasks in response to all sorts of events, so this needs to
    be hooked up to a `port` to ensure they get run.
-}
type alias App model =
    { html : Signal Html
    , model : Signal model
    , tasks : Signal (Task.Task Never ())
    }


{-| Start an application. It requires a bit of wiring once you have created an
`App`. It should pretty much always look like this:

    app =
        start { init = init, view = view, update = update, inputs = [] }

    main =
        app.html

    port tasks : Signal (Task.Task Never ())
    port tasks =
        app.tasks

So once we start the `App` we feed the HTML into `main` and feed the resulting
tasks into a `port` that will run them all.
-}
start : Config model action -> App model
start config =
    let
        singleton action = [ action ]

        -- messages : Signal.Mailbox (List action)
        messages =
            Signal.mailbox []

        -- address : Signal.Address action
        address =
            Signal.forwardTo messages.address singleton

        -- updateStep : (action, Time) (model, Effects action) -> (model, Effects action)
        updateStep (action, time) (oldModel, accumulatedEffects) =
            let
                (newModel, additionalEffects) = config.update action time oldModel
            in
                (newModel, Effects.batch [accumulatedEffects, additionalEffects])

        -- update : (Time, (List action)) -> (model, Effects action) -> (model, Effects action)
        update (time, actions) (model, _) =
            List.foldl updateStep (model, Effects.none) (List.map (\a -> (a, time)) actions)

        -- inputs : Signal (List action)
        inputs =
            Signal.mergeMany (messages.signal :: List.map (Signal.map singleton) config.inputs)

        -- inputsWithTime : Signal (Time, (List action))
        inputsWithTime =
          Time.timestamp inputs

        -- effectsAndModel : Signal (model, Effects action)
        effectsAndModel =
            Signal.foldp update config.init inputsWithTime

        model =
            Signal.map fst effectsAndModel
    in
        { html = Signal.map (config.view address) model
        , model = model
        , tasks = Signal.map (Effects.toTask messages.address << snd) effectsAndModel
        }

elm 榆树组件模板

榆树组件模板

app.elm
module App (main) where
{-| template
-}

import Counter

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Signal exposing (Signal, Address)

main: Signal Html
main = Signal.map (view actions.address) model

-- Model
type alias Model =
  { top: Counter.Model
  , bottom: Counter.Model
  }

init: Int -> Model
init val =
  { top = Counter.init val
  , bottom = Counter.init val
  }

model: Signal Model
model = Signal.foldp update (init 0) actions.signal

-- Action
type Action
  = NoOp
  | ResetAll
  | Top Counter.Action
  | Bottom Counter.Action

update: Action -> Model -> Model
update action model =
  case action of
    NoOp -> model
    ResetAll -> { model | top = Counter.update Counter.reset model.top
                        , bottom = Counter.update Counter.reset model.bottom }
    Top action -> { model | top = Counter.update action model.top }
    Bottom action -> { model | bottom = Counter.update action model.bottom }

actions: Signal.Mailbox Action
actions =
  Signal.mailbox NoOp

-- View
view: Address Action -> Model -> Html
view address model =
  div []
    [ div []
        [ text "top: "
        , Counter.view (Signal.forwardTo address Top) model.top
        ]
    , div []
        [ text "bottom: "
        , Counter.view (Signal.forwardTo address Bottom) model.bottom
        ]
    , button [onClick address ResetAll] [text "reset"]
    ]
  
Counter.elm
module Counter (Model, init, Action, reset, update, view) where
{-| template
-}

import Html exposing (Html, span, input, button, text)
import Html.Attributes exposing (disabled, value)
import Html.Events exposing (onClick)
import Signal exposing (Signal, Address)

-- Model
type alias Model = Int

init: Int -> Model
init val = val

-- Action
type Action
  = NoOp
  | Reset
  | Increment
  | Decrement

reset = Reset

update: Action -> Model -> Model
update action model =
  case action of
    NoOp -> model
    Reset -> 0
    Increment -> model + 1
    Decrement -> model - 1

-- View
view: Address Action -> Model -> Html
view address model =
  span []
    [ button [onClick address Decrement] [text "-"]
    , input [disabled True, value (toString model)] []
    , button [onClick address Increment] [text "+"]
    ]
  

elm 取自http://t.co/7rH5lfyAvt的教程,并修复了自拍摄以来Elm的一些变化。

取自http://t.co/7rH5lfyAvt的教程,并修复了自拍摄以来Elm的一些变化。

gistfile1.elm
import Mouse
import Window
import Random
import Text

(width, height) = (400, 400)
(hWidth, hHeight) = (width / 2, height / 2)

relativeMouse : (Int, Int) -> (Int, Int) -> (Int, Int)
relativeMouse (ox, oy) (x, y) = (x - ox, -(y - oy))

center : (Int, Int) -> (Int, Int)
center (w, h) = ( w // 2, h // 2)

type Vec = (Float, Float)

vecAdd  : Vec -> Vec -> Vec
vecAdd (ax, ay) (bx, by) = (ax + bx, ay + by)

vecSub  : Vec -> Vec -> Vec
vecSub (ax, ay) (bx, by) = (ax - bx, ay - by)

vecLen : Vec -> Float
vecLen (x, y) = sqrt (x * x + y * y)

vecMulS : Vec -> Time -> Vec
vecMulS (x, y) t = (x * t, y * t)

type Pill = {pos:Vec, vel:Vec, rad:Float, col:Color}

defaultPill = { pos = (0, hHeight)
                ,vel = (0, -500)
                ,rad = 15
                ,col = lightRed
              }

newPill : Float -> Color -> Pill
newPill x col = { defaultPill | pos <- (x, hHeight)
                              , col <- col }

defaultPlayer = { defaultPill | pos <- (0, (-hHeight - defaultPill.rad))
                              , col <- black }

data State = Play | GameOver | Start
type Game = {player: Pill, pills: [Pill], score: Int, state: State}

defaultGame = { player = defaultPlayer
              , pills = []
              , score = 0
              , state = Start
              }

data Event = Tick (Time, (Int, Int)) | Add Pill | Click

stepPlay : Event -> Game -> Game
stepPlay event g =
          case event of
            Tick (t, mp) -> let hit pill = (vecLen <| vecSub g.player.pos pill.pos) < g.player.rad + pill.rad
                                unculled = filter (\ {pos} -> snd pos > -hHeight ) g.pills
                                untouched = filter (not << hit) unculled
                                touched = filter hit unculled

                                hitCol c = not <| isEmpty <| filter (\{col} -> col == c) touched
                                hitBlue = hitCol lightBlue
                                hitRed = hitCol lightRed

                                out = let (x, y) = mp in abs (toFloat x) > hWidth || abs (toFloat y) > hHeight

                                g' = { g | player <- stepPlayer mp g.player
                                     , pills <- map (stepPill t) untouched
                                     , score <- if hitBlue then g.score + 1 else g.score }
                            in if hitRed || out then { defaultGame | score <- g'.score
                                                             , state <- GameOver } else g'
            Add p        -> { g | pills <- p :: g.pills }
            Click        -> g

click : Event -> Bool
click event =
  case event of
    Click -> True
    _     -> False

stepGame : Event -> Game -> Game
stepGame event ({state} as g) =
  let playGame = { defaultGame | state <- Play }
      toPlay = if click event then playGame else g
  in case state of
    Play -> stepPlay event g
    GameOver -> toPlay
    Start -> toPlay

stepPill : Time -> Pill -> Pill
stepPill t p = { p | pos <- vecAdd p.pos <| vecMulS p.vel t }

stepPlayer : (Int, Int) -> Pill -> Pill
stepPlayer (x, y) p = { p | pos <- (toFloat x, toFloat y) }

tf : Float -> Float -> String -> Form
tf y scl str =
  toText str |> Text.color grey
              |> centered
              |> toForm
              |> scale scl
              |> move (0, y)

render : (Int, Int) -> Game -> Element
render (w, h) game =
  let formPill {rad, col, pos} = circle rad |> filled col
                                             |> move pos

      txts = case game.state of
        Start -> [
                      tf 70 4 "BluePiLL",
                      tf 0 2 "Click to Start"
                    ]
        Play -> [ tf 0 4 (show game.score) ]
        GameOver -> [
                      tf 70 4 "Game Over",
                      tf 0 4 (show game.score),
                      tf -50 2 "Click to Restart"
                    ]

      forms = txts ++ (map formPill <| game.player :: game.pills)
  in color grey <| container w h middle
                 <| color white
                 <| collage width height forms

rand fn sig = lift fn (Random.float sig)

randX = rand (\r -> (width * r) - hWidth)

randCol = rand (\r -> if r < 0.1 then lightBlue else defaultPill.col)

interval = (every (second * 0.5))
event = merges [ lift Tick input
                , lift2 (\x col -> Add (newPill x col )) (randX interval) (randCol interval)
                , lift (\_ -> Click) Mouse.isDown
                ]

delta = (fps 30)
input = (,) <~ lift inSeconds delta
             ~ sampleOn delta (lift2 relativeMouse (lift center Window.dimensions)  Mouse.position)
main = render <~ Window.dimensions ~ foldp stepGame defaultGame event

elm gistfile1.elm

gistfile1.elm
import Mouse
import Window

main = lift2 scene Window.dimensions clickPositions

clickPositions = sampleOn Mouse.clicks Mouse.position

circ = (filled red (circle 80)) 

scene (w,h) (x,y) =
    collage w h [ circ |> move (toFloat x - toFloat w / 2, toFloat h / 2 - toFloat y)]