Fresheyeball / elm-return / Return

Type

Modeling the update tuple as a Monad similar to Writer


type alias Return msg model =
( model, Platform.Cmd.Cmd msg )


type alias ReturnF msg model =
Return msg model -> Return msg model

Mapping

map : (a -> b) -> Return msg a -> Return msg b

Transform the Model, the Cmd will be left untouched

map2 : (a -> b -> c) -> Return msg a -> Return msg b -> Return msg c

Combine 2 Returns with a function

map2
  (\modelA modelB -> { modelA | foo = modelB.foo })
  retA
  retB

map3 : (a -> b -> c -> d) -> Return msg a -> Return msg b -> Return msg c -> Return msg d

map4 : (a -> b -> c -> d -> e) -> Return msg a -> Return msg b -> Return msg c -> Return msg d -> Return msg e

map5 : (a -> b -> c -> d -> e -> f) -> Return msg a -> Return msg b -> Return msg c -> Return msg d -> Return msg e -> Return msg f

andMap : Return msg a -> Return msg (a -> b) -> Return msg b

Map an Return into a Return containing a Model function

mapWith : (a -> b) -> Platform.Cmd.Cmd msg -> Return msg a -> Return msg b

Transform the Model of and add a new Cmd to the queue

mapCmd : (a -> b) -> Return a model -> Return b model

Map on the Cmd.

mapBoth : (a -> b) -> (c -> d) -> Return a c -> Return b d

Map over both the model and the msg type of the Return. This is useful for easily embedding a Return in a Union Type. For example

import Foo

type Msg = Foo Foo.Msg
type Model = FooModel Foo.Model

...

update : Msg -> Model -> Return Msg Model
update msg model =
   case msg of
      Foo foo -> Foo.update foo model.foo
        |> mapBoth Foo FooModel

dropCmd : ReturnF msg model

Drop the current Cmd and replace with an empty thunk

Piping

piper : List (ReturnF msg model) -> ReturnF msg model

pipel : List (ReturnF msg model) -> ReturnF msg model

zero : ReturnF msg model

piperK : List (a -> Return x a) -> a -> Return x a

Compose updaters from the right

pipelK : List (a -> Return x a) -> a -> Return x a

Compose updaters from the left

Basics

singleton : model -> Return msg model

Create a Return from a given Model

andThen : (a -> Return msg b) -> Return msg a -> Return msg b

foo : Model -> Return Msg Model
foo ({ bar } as model) =
    -- forking logic
    if
        bar < 10
        -- that side effects may be added
    then
        ( model, getAjaxThing )
        -- that the model may be updated

    else
        ( { model | bar = model.bar - 2 }, Cmd.none )

They are now chainable with andThen...

resulting : Return msg { model | bar : Int }
resulting =
    myReturn
        |> andThen foo
        |> andThen foo
        |> andThen foo

Here we changed up foo three times, but we can use any function of type (a -> Return msg b).

Commands will be accumulated automatically as is the case with all functions in this library.

andThenK : (a -> Return x b) -> (b -> Return x c) -> a -> Return x c

Kleisli composition

Write Cmds

return : model -> Platform.Cmd.Cmd msg -> Return msg model

Construct a new Return from parts

command : Platform.Cmd.Cmd msg -> Return msg model -> Return msg model

Add a Cmd to a Return, the Model is uneffected

effect_ : Respond msg model -> Return msg model -> Return msg model

Add a Cmd to a Return based on its Model, the Model will not be effected

Fancy non-sense

sequence : List (Return msg model) -> Return msg (List model)

flatten : Return msg (Return msg model) -> Return msg model