Werner Echezuria
Werner Echezuria

Reputation: 622

Pattern match a polymorphic type in a concrete type in Elm

I'm using elm-form: https://github.com/etaque/elm-form/, and I need to pattern match a polymorphic type into a concrete type, however I got the next error:

The pattern matches things of type:

    TranslationId

But the values it will actually be trying to match are:

    e

Hint: Your type annotation uses type variable `e` which means any type of value
can flow through. Your code is saying it CANNOT be anything though! Maybe change
your type annotation to be more specific? Maybe the code has a problem? More at:
<https://github.com/elm-lang/elm-compiler/blob/0.18.0/hints/type-annotations.md>

The code in question is this:

translateError : ErrorValue e -> String
translateError error =
    case error of
        InvalidEmail ->
            translate English ErrInvalidEmail

        Empty ->
            translate English ErrEmpty

        CustomError PasswordNotMatch ->
            translate English PasswordNotMatch

        x ->
            toString x

ErrorValue type https://github.com/etaque/elm-form/blob/f9480cb8646ebc9f78f13d3a7482c463c5275776/src/Form/Error.elm#L19:

type ErrorValue e
    = Empty
    | InvalidString
    | InvalidEmail
    | InvalidUrl
    | InvalidFormat
    | InvalidInt
    | InvalidFloat
    | InvalidBool
    | InvalidDate
    | SmallerIntThan Int
    | GreaterIntThan Int
    | SmallerFloatThan Float
    | GreaterFloatThan Float
    | ShorterStringThan Int
    | LongerStringThan Int
    | NotIncludedIn
    | CustomError e

TranslationId type https://github.com/werner/madison-elm/blob/master/src/elm/Translations/Utils.elm#L9:

type TranslationId
    = ErrInvalidEmail
    | PasswordNotMatch
    | ErrEmpty

I came up with a solution, but it looks weird and I'm not sure if it's the right one https://github.com/werner/madison-elm/blob/master/src/elm/Translations/FormErrors.elm#L7:

translateError : ErrorValue e -> String
translateError error =
    case error of
        InvalidEmail ->
            translate English ErrInvalidEmail

        Empty ->
            translate English ErrEmpty

        CustomError e ->
            case (toString e) of
                "PasswordNotMatch" ->
                    translate English PasswordNotMatch
                x ->
                    toString x

        x ->
            toString x

Upvotes: 1

Views: 532

Answers (1)

Simon H
Simon H

Reputation: 21005

As @reactormonk says, you are not addressing the type variable in your type definition. elm-form provides flexibility in the custom error through this type variable, which you have to supply yourself if you want to use custom errors (if you do not then you can use the variable throughout your code with no problem).

In particular ErrorValue has a type variable e that you need to specify: it does not matter in the code that does not use the CustomError constructor, but does matter in translateError because you are trying to pattern match on CustomError. It looks as though the type you want is TranslationId so you want

translateError : ErrorValue TranslationId -> String
translateError error =
    case error of
        InvalidEmail ->
            translate English ErrInvalidEmail

        Empty ->
            translate English ErrEmpty

        CustomError PasswordNotMatch ->
            translate English PasswordNotMatch

        x ->
            toString x

Upvotes: 2

Related Questions