chrilves/elm-io/1.1.0

NOTE: this package is not compatible with Elm 0.19.1

IO

This module provides a monadic interface for The Elm Architecture.

Basically IO is a monad enabing two kinds of effects :

  • model modification (it is a state monad)
  • Cmd commands
type IO model a

Monadic interface for The Elm Architecture.

A value of type IO model a is an effectful computation that can modify the model model, perform commands and contains values of type a.

Runing an Elm application with IO

This module port the four main way of running an Elm application to IO.

type alias Program flags model msg =
Program flags model (IO model msg)

Program using IO.

{ init : ( model, IO model msg )
, update : msg -> IO model msg
, subscriptions : model -> Sub (IO model msg)
}
-> Program Never model msg

Port of Platform.program with IO.

{ init : ( model, IO model msg )
, update : msg -> IO model msg
, subscriptions : model -> Sub (IO model msg)
, view : model -> Node (IO model msg)
}
-> Program Never model msg

Port of VirtualDom.program with IO (also works with Html).

{ init : flags -> ( model, IO model msg )
, update : msg -> IO model msg
, subscriptions : model -> Sub (IO model msg)
}
-> Program flags model msg

Port of Platform.programWithFlags with IO.

{ init : flags -> ( model, IO model msg )
, update : msg -> IO model msg
, subscriptions : model -> Sub (IO model msg)
, view : model -> Node (IO model msg)
}
-> Program flags model msg

Port of VirtualDom.programWithFlags with IO (also works with Html).

Lifting values and commands into IO

pure : a -> IO model a

Returns an IO whose only effect is containing the value given to pure.

lift : Cmd a -> IO model a

Lift a Cmd as an IO.

liftM : CmdM a -> IO model a

Lift a CmdM as an IO.

liftUpdate : (model -> ( model, Cmd a )) -> IO model a

Lift a classic update function into an IO.

none : IO model a

An IO doing nothing (an containing no values!).

The model as a state

get : IO model model

An IO that returns the current model.

set : model -> IO model ()

An IO that sets the model.

modify : (model -> model) -> IO model ()

A IO that modify the model.

Classic monadic operations

map : (a -> b) -> IO model a -> IO model b

Map a function over an IO.

Laws

  • map (f >> g) = (map f) >> (map g)
  • map identity = identity
bind : (a -> IO model b) -> IO model a -> IO model b

Chains IOs.

If you have an IO model a and a function which given a a can give you an IO model b depending on the value of type a given to the function. Then bind gives you an IO model b that will run the first IO and then apply the function.

Laws

  • bind pure = identity
  • bind (f >> pure) = map f
  • (bind f) >> (bind g) = bind (a -> bind g (f a))
join : IO model (IO model a) -> IO model a

Flatten an IO containing an IO into a simple IO.

Laws

  • join (pure m) = m
ap : IO model (a -> b) -> IO model a -> IO model b

Transform an IO containing functions into functions on IO It enable to easily lift functions to IO.

Laws

  • ap (pure identity) = identity
  • ap (pure (f >> g)) = ap (pure f) >> ap (pure g)
traverse : (a -> IO model b) -> List a -> IO model (List b)

You can think of traverse like a map but with effects. It maps a function performing IO effects over a list.

mapM : List (IO model a) -> IO model (List a)

Transform a list of IO into an IO of list.

Passing from a model to another

lens : Lens a b -> IO a msg -> IO b msg

Congruence by a Lens on an IO.

It would be silly to force users to redefine every IO for each application model. Lenses enable to lift an IO action on a model a to the same IO but action on a model b.

You can then define your IO on the minimal model and lift them to you real application's model when needed.

select : Select a b -> IO a msg -> IO b msg

Congruence by a Select on an IO. Just like lenses but with Select.

Transform IO into regular Elm

{ y
| init : ( model, IO model msg )
, update : msg -> IO model msg
}
-> { y
| init : ( model, Cmd (IO model msg) )
, update : IO model msg -> model -> ( model, Cmd (IO model msg) )
}

Transform a program using IO into a normal program.

{ y
| init : flags -> ( model, IO model msg )
, update : msg -> IO model msg
}
-> { y
| init : flags -> ( model, Cmd (IO model msg) )
, update : IO model msg -> model -> ( model, Cmd (IO model msg) )
}

Transform a program using IO into a normal program.

Unsafe operations (You've been warned!)

batch : List (IO model a) -> IO model a

Combine a list of IO. Its use is strongly discouraged! Use mapM instead!

combine : IO model a -> IO model a -> IO model a

Combine two IO. Its use is strongly discouraged! Use *mapM instead!