21
Elm Signals and Suggestions

Elm Signals and Suggestions. Working online In general, I found working online at to be the best way to program Elm

Embed Size (px)

Citation preview

Page 1: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Elm

Signals and Suggestions

Page 2: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Working online

In general, I found working online at http://elm-lang.org/try to be the best way to program Elm Instant feedback, so you can try one change at a time and see if it worked No good way to save your work; I did an occasional copy-all and paste

into Sublime Text The images used in the examples are on the server, not locally, so you

can’t readily use them in your own program I installed Elm and used the elm repl to test single expressions and very

small bits of code The REPL is especially useful for entering expressions to find out their

type > Signal.map

<function: map> : (a -> b) -> Signal.Signal a -> Signal.Signal b

2

Page 3: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Program structure Elm programs have a structure very similar to MVC (Model-View-Controller) The structure is Model - Update - View, or sometimes Model - Update - View -

Signals In Elm

The Model is typically just data, describing the current state of the program; typically this is in the form of a record named model

The Update is a set of pure functions; typically there is a function named update with a signature similar to Input -> Model -> Model

The View is a set of functions whose purpose is to display the current state; typically there is a function named view with a signature something like Input -> Model -> Element

The Signals part includes a function named main; it collects signals together and bundles them up, sends them to update to get a new program state, and sends the result to view

3

Page 4: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Mouse signals

import Mouse exposing (..) position : Signal ( Int, Int ) x : Signal Int y : Signal Int isDown : Signal Bool clicks : Signal ()

4

Page 5: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Keyboard signals

import Keyboard exposing (..) Mouse.position : Signal (Int, Int) arrows : Signal { x : Int, y : Int } wasd : Signal { x : Int, y : Int } enter, space, ctrl, shift, alt, meta are all Signal Bool

type alias KeyCode = Int isDown : KeyCode -> Signal Bool keysDown : Signal (Set KeyCode) presses : Signal KeyCode -- most recent key

pressed5

Page 6: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Time signals

import Time exposing (..) fps : number -> Signal Time

fps (frames per second) will produce a signal the given number of times every second

fpsWhen : number -> Signal Bool -> Signal Time Same as the fps function, but you can turn it on and off

every : Time -> Signal Time Takes a time interval t and produces a signal updated every t

delay : Time -> Signal a -> Signal a Delays a time signal

There a few additional functions6

Page 7: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Window signals

import Window exposing (..) dimensions : Signal ( Int, Int ) width : Signal Int height : Signal Int

When you embed Elm in a <div> it gives the dimensions of the container, not the whole window

7

Page 8: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Monads

Signal is a monad type Signals, by definition, vary over time Clearly, this is inappropriate for a pure functional language Monads “isolate” impure operations

The main function in the Signals part of an Elm program:• Collects signals together and bundles them up• Extracts the data from the signals and sends them to the

pure function update to get a new program state• Sends the new program state to view

8

Page 9: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Bind

Remember “bind” (>>=) in Haskell? bind takes a value out of a monad, applies a function to it, and puts

the result back into a monad:(>>=) :: Monad m => m a -> (a -> m b) -> m b

Elm has something similar but not identical Signal.map : (a -> b) -> Signal a -> Signal b

This allows us to take a Signal a, use it to call a pure function (a -> b), and get the result as a Signal b

The arguments are reversed from those of >>= but in the same order as those of List.map List.map : (a -> b) -> List a -> List b

<~ is an alias for Signal.map9

Page 10: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Signal.mapn Signal.map applies a pure function to the value inside a Signal, producing

another Signal Signal.map : (a -> b) -> Signal a -> Signal b

However, you often have pure functions that take more than a single argument map2 : (a -> b -> result) -> Signal a -> Signal b -> Signal result The result type is, of course, up to the supplied function, but is often a tuple

map3 : (a -> b -> c -> result) -> Signal a -> Signal b -> Signal c -> Signal result

map4 : (a -> b -> c -> d -> result) -> Signal a -> Signal b -> Signal c -> Signal d -> Signal result

map5 -- the obvious type is omitted for reasons of space

10

Page 11: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Warning! lift

Elm is a new and rapidly changing language If you find examples using the functions lift, lift2, lift3, etc., these functions no longer exist

They have been replaced by map, map2, map3, etc. The old functions have the same signature as the new,

and as far as I know, is just a name change

11

Page 12: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Sampling

import Signal exposing (..) sampleOn : Signal a -> Signal b -> Signal b

Sample from the second input every time an event occurs on the first input. For example, (sampleOn clicks (every second)) will give the approximate time of the latest click

The value of the first signal (Signal a) is discarded

I believe that the purpose of sampleOn is to restrict the number of events that must be handled by the update and view parts of the program Mouse.position can probably produce hundreds of events

a second

12

Page 13: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

foldp

foldp folds signals “over time”

From the documentation:foldp : (a -> state -> state) -> state -> Signal a -> Signal stateCreate a past-dependent signal. Each update from the incoming signals will be used to step the state forward. The outgoing signal represents the current state.

13

Page 14: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Mario example I

main : Signal Elementmain = Signal.map2 view Window.dimensions (Signal.foldp update mario input)

view : (Int, Int) -> Model -> Element

update : (Float, Keys) -> Model -> Model

14

Page 15: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Mario example II

main : Signal Elementmain = Signal.map2 view Window.dimensions (Signal.foldp update mario input)

input : Signal (Float, Keys)input = let delta = Signal.map (\t -> t/20) (fps 30) in Signal.sampleOn delta (Signal.map2 (,) delta Keyboard.arrows)

15

Page 16: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Modified Mario I

I modified the Mario example to also accept mouse position signals

main : Signal Elementmain = Signal.map3 view Window.dimension Mouse.position (Signal.foldp update mario input)

view : (Int, Int) -> (Int, Int) -> Model -> Element

update : (Float, Keys) -> Model -> Model16

Page 17: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Modified Mario II

main : Signal Elementmain = Signal.map3 view Window.dimension Mouse.position (Signal.foldp update mario input)

input : Signal (Float, Keys, Location)input = let delta = Signal.map (\t -> t/20) (fps 30) in Signal.sampleOn delta (Signal.map3 (,,) delta Keyboard.arrows Mouse.position)

17

Page 18: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Modified Mario III type alias Model = { x : Float , y : Float , vx : Float , vy : Float , dir : Direction , mouse : (Int, Int) }

update : (Float, Keys, Location) -> Model -> Modelupdate (dt, keys, position) mario = mario |> gravity dt |> jump keys |> walk keys |> physics dt |> attract position -- defined as type alias Location = (Int, Int)

18

Page 19: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Questions main : Signal Elementmain = Signal.map3 view Window.dimension Mouse.position (Signal.foldp update mario input)

input : Signal (Float, Keys, Location)input = let delta = Signal.map (\t -> t/20) (fps 30) in Signal.sampleOn delta (Signal.map3 (,,) delta Keyboard.arrows Mouse.position)

Why isn’t Window.dimension handled in input? Why do I need to mention Mouse.position twice?

19

Page 20: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

Collage example A Collage is used to display things on the screen view : (Int, Int) -> (Int, Int) -> Model -> Elementview (w',h') mario = let -- many definitions omitted: w, h, marioImage, etc. in collage w' h' [ rect w h |> filled (rgb 174 238 238) , rect w 50 |> filled (rgb 74 167 43) |> move (0, 24 - h/2) , marioImage |> toForm |> move position ]

20

Page 21: Elm Signals and Suggestions. Working online  In general, I found working online at  to be the best way to program Elm

21

The End