The point is to avoid using Cmd.map, right?
What we want is Api.elm knows how to get a Thing from a server, but doesn’t want to deal with what to do with the response.
And Main.elm, and other clients of Api.elm, want to get a Thing from a remote server so they can do awesome things with it, but they don’t want to deal with how to get it.
So Api.elm can be lazy about doing things with Things:
module Api exposing (getSomething)
{-| I'll get a Thing for you, just tell me what you want done with it.
For example, I could put it into some kind of msg for you, then I'll give
you a Cmd you can invoke to get *that kind of msg* eventually.
-}
getThing : (Result Http.Error Thing -> msg) -> Cmd msg
getThing constructor =
Http.request
{ method : "GET"
, headers : []
, url : "http://thingServer.someplace.com/"
, body : Http.emptyBody
, expect : Http.expectJson constructor thingDecoder
, timeout : Nothing
, tracker : Nothing
}
And Main.elm is lazy about how to get things:
{-| When I init, the Api is going to do some work for me, and then
I'll get a GotThing message that hopefully has a Thing in it!
-}
main : Program () MyAwesomeModel MyMainMessageType
main =
Browser.element
{ init : () -> ( init, Api.getThing GotThing )
, view : view
, update : update
, subscriptions : always Sub.none
}
type MyMainMessageType
= GotThing (Result Http.Error Thing)
update :
MyMainMessageType
-> MyAwesomeModel
-> ( MyAwesomeModel, Cmd MyMainMessageType )
update msg model =
case msg of
GotThing (Ok thing) ->
Thing.doAllTheThings thing
GotThing (Err error) ->
dealWith error
When they said suggested passing ( a -> msg), that translated to my example as passing the type constructor GotThing in Api.getThing GotThing. Note that GotThing by itself has the type ( Result Http.Error Thing -> MyMainMessageType), in other words its a constructor for values of MyMainMessageType. And that Api.getThing takes as its first argument a ( Result Http.Error Thing -> msg), or in other words, it just wants a message constructor for some type of msg so that it can cram the Thing it gets somewhere. It returns a Cmd that could produce that type of msg eventually.