elm-reader

Reader type in Elm

MIT License

Stars
7
Committers
1

Reader

A Reader is a handy type that is used for providing a shared "environment" to computations. It helps to solve the problem of passing around the same values or configurations to many functions. It is also often used as a way of doing dependency injections. In such cases by using a Reader the concern of passing the relevant context is mostly handled at the very peripheri of the application

Consider the following


type alias DogImages =
    { status : String
    , message : List String
    }
    
requestDogBreed : String -> String -> Json.Decode.Decoder a -> Http.Request a
requestDogBreed apiKey apiPath decoder =
    Http.get ("https://dog.ceo/api/breed/" ++ apiPath ++ "&apiKey=" ++ apiKey) decoder


requestShibaImages :  String -> String -> Http.Request DogImages
requestShibaImages apiKey queryParameters =
    requestDogBreed apiKey ("shiba/images" ++ queryParameters) decodeDogImages


requestOneShibaImage : String -> Http.Request DogImages
requestOneShibaImage apiKey =
    requestShibaImages apiKey "?limit=10"

If you look at requestOneShibaImage you’ll see apiKey is not used, but is passed through to the other functions until it reaches requestDogBreed where it is actually used. Such kind of boilerplate can be avoided with the usage of a Reader type

Instead of apiKey being passed down to each function, we can use a Reader and rewrite this in such a way that the context will get passed implicitly.

requestDogBreed : String -> Json.Decode.Decoder a -> Reader String (Http.Request a)
requestDogBreed apiPath decoder =
    Reader (\apiKey -> Http.get ("https://dog.ceo/api/breed/" ++ apiPath ++ "&apiKey=" ++ apiKey) decoder )


requestShibaImages : String -> Reader String (Http.Request DogImages)
requestShibaImages queryParameters =
    requestDogBreed ("shiba/images" ++ queryParameters) decodeDogImages


requestOneShibaImage : Reader String (Http.Request DogImages)
requestOneShibaImage =
    requestShibaImages "?limit=1"

Now the intermediate functions requestShibaImages and requestOneShibaImage no longer have to take in and pass apiKey around.

When we finally want to send the Http Request we can use the run function to pass in the context to the Reader and retrive the value i.e the final Request

type Msg
    = LoadShibaImages (Result Http.Error DogImages)

send : Cmd Msg
send =
    Http.send LoadShibaImages <|
        run requestOneShibaImage "123456"

About BigBinary

elm-reader is maintained by BigBinary. BigBinary is a software consultancy company. We build web and mobile applications using Ruby on Rails, React.js, React Native and Elm.