ajmurmann
ajmurmann

Reputation: 1635

Elm type confusion

I started on my first, simple web app in Elm. Most of my code is currently adapted from https://github.com/rtfeldman/elm-spa-example. I am working against a API that will give me a authToken in the response header. I have a AuthToken type that is supposed to represent that token. Taking the value out of the header and converting it to a result that's either a error String or a AuthToken is causing trouble. I expected that I could just say I am returning a AuthToken, return a String and it would be fine because my AuthTokens right now are just Strings. It seems like there clearly is something about Elm types I am not understanding.

Here is the definition of AuthToken:

type AuthToken
  = AuthToken String

and my way too complicated function that for now just tries to do some type changes (later I want to also do work on the body in here):

authTokenFromHeader : String -> Http.Response String -> Result String AuthToken
authTokenFromHeader name resp =
    let
        header = extractHeader name resp
    in
    case header of
        Ok header ->
            let
                token : Result String AuthToken
                token = Ok (AuthToken header)
            in
            token
        Err error -> Err error

I expected the happy case would return a Ok result with the string from the response header converted to a AuthToken as its value. Instead I am getting Cannot find variable 'AuthToken'. From the documentation I expected to get a constructor with the same name as the type. If I just use Ok header, the compiler is unhappy because I am returning Result String String instead of the promised Result String AuthToken.

What's the right approach here?

Upvotes: 2

Views: 129

Answers (1)

robx
robx

Reputation: 2329

The code looks fine as is. The error message indicates that type AuthToken has been defined in a different module and not imported completely to the module that defines authTokenFromHeader. You can read about Elm's module system in the Elm guide: Modules.

A possible fix, assuming that type AuthToken is defined in module Types, and authTokenFromHeader is defined in module Net, is:

Types.elm:

module Types exposing (AuthToken(..))

type AuthToken = AuthToken String

Net.elm:

module Net exposing (authTokenFromHeader)

import Types exposing (AuthToken(..))

authTokenFromHeader : String -> Http.Response String -> Result String AuthToken
authTokenFromHeader name resp =
    ...

Note the use of AuthToken(..) instead of just AuthToken, which ensures that the type as well as the type constructors are imported/exported.

Or just move the definition of type AuthToken into the same file as the definition of authTokenFromHeader.

Upvotes: 4

Related Questions