chrilves/elm-io/1.1.0

NOTE: this package is not compatible with Elm 0.19.1

CmdM

This module provides a monadic interface for commands.

Basically CmdM is like Cmd but is a monad, which means you can chain effects as you like!

type CmdM msg

Monadic interface for commands.

A value of type CmdM msg is an effectful computation that can perform commands and contains values of type msg.

Runing an Elm application with CmdM

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

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

Program using IO.

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

Port of Platform.program with IO.

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

Port of VirtualDom.program with CmdM (also works with HTML).

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

Port of Platform.programWithFlags with CmdM.

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

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

Lifting values and commands into CmdM

pure : a -> CmdM a

Returns a CmdM whose only effect is containing the value given to pure.

lift : Cmd a -> CmdM a

Transforms an Elm command into a monadic command CmdM.

none : CmdM a

A CmdM doing nothing (an containing no values!).

Classic monadic operations

map : (a -> b) -> CmdM a -> CmdM b

Map a function over an CmdM.

Laws

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

Chains CmdMs.

If you have a CmdM a and a function which given a a can give you a CmdM b depending on the value of type a given to the function. Then bind gives you a CmdM b that will run the first CmdM 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 : CmdM (CmdM a) -> CmdM a

Flatten a CmdM containing a CmdM into a simple CmdM.

Laws

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

Transform a CmdM containing functions into functions on CmdM. It enable to easily lift functions to CmdM.

Laws

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

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

mapM : List (CmdM a) -> CmdM (List a)

Transform a list of CmdM into an CmdM of list.

Transform IO into regular Elm

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

Transform a program using IO into a normal program.

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

Transform a program using CmdM into a normal program.

Folding

If you need to convert CmdM to something else, this is the way.

fold : (a -> r) -> (Cmd r -> r) -> CmdM a -> r

Catamorphism for CmdM. Strict version.

lazyFold : (a -> r) -> ((() -> Cmd r) -> r) -> CmdM a -> r

Catamorphism for CmdM. Lazy version.

Unsafe operations (You've been warned!)

batch : List (CmdM a) -> CmdM a

Group commands in a batch. Its behavior may not be what you expect! I strongly discourage you from using it. Use mapM instead.

combine : CmdM a -> CmdM a -> CmdM a

Group commands in a batch. Its behavior may not be what you expect! I strongly discourage you from using it. Use mapM instead.