chrilves / elm-io / 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 alias CmdM msg =
Internal.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 =
Platform.Program flags model (CmdM msg)

Program using CmdM.

element : { init : flags -> ( model, CmdM msg ), view : model -> Html (CmdM msg), update : msg -> model -> ( model, CmdM msg ), subscriptions : model -> Platform.Sub.Sub (CmdM msg) } -> Program flags model msg

Transform an element program using CmdM into a normal element program.

document : { init : flags -> ( model, CmdM msg ), view : model -> Browser.Document (CmdM msg), update : msg -> model -> ( model, CmdM msg ), subscriptions : model -> Platform.Sub.Sub (CmdM msg) } -> Program flags model msg

Transform a document program using CmdM into a normal document program.

application : { init : flags -> Url -> Browser.Navigation.Key -> ( model, CmdM msg ), view : model -> Browser.Document (CmdM msg), update : msg -> model -> ( model, CmdM msg ), subscriptions : model -> Platform.Sub.Sub (CmdM msg), onUrlRequest : Browser.UrlRequest -> CmdM msg, onUrlChange : Url -> CmdM msg } -> Program flags model msg

Transform an application program using CmdM into a normal application program.

Lifting values and commands into CmdM

pure : a -> CmdM a

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

lift : Platform.Cmd.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

andThen : (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 andThen gives you a CmdM b that will run the first CmdM and then apply the function.

Laws

join : CmdM (CmdM a) -> CmdM a

Flatten a CmdM containing a CmdM into a simple CmdM.

Laws

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

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

Flipped version of ap. To be used like:

pure f |> flap arg1 |> flap arg2 ...

compose : (b -> CmdM c) -> (a -> CmdM b) -> a -> CmdM c

Composition of monadic functions

seq : CmdM b -> CmdM a -> CmdM b

Run the second argument, ignore the result, then run the first one. To be used in

first |> seq second

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 CmdM into regular Elm

transform : (msg -> model -> ( model, CmdM msg )) -> { update : CmdM msg -> model -> ( model, Platform.Cmd.Cmd (CmdM msg) ), initTransformer : ( model, CmdM msg ) -> ( model, Platform.Cmd.Cmd (CmdM msg) ) }

Transform a program using CmdM into a normal program.

Batch operations

Beware that batch operations might not do what you think. The execution order of messages and commands is not defined.

batch : List a -> CmdM a

Send messages in batch

batchM : List (CmdM a) -> CmdM a

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