模式匹配Elm中具体类型的多态类型

时间:2017-01-01 13:35:15

标签: elm

我使用elm-form:https://github.com/etaque/elm-form/,我需要将多态类型匹配到具体类型,但是我得到了下一个错误:

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>

有问题的代码是:

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类型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类型https://github.com/werner/madison-elm/blob/master/src/elm/Translations/Utils.elm#L9

type TranslationId
    = ErrInvalidEmail
    | PasswordNotMatch
    | ErrEmpty

我想出了一个解决方案,但它看起来很奇怪,我不确定它是否是正确的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

1 个答案:

答案 0 :(得分:2)

正如@reactormonk所说,您没有在类型定义中处理类型变量。 elm-form通过此类型变量提供自定义错误的灵活性,如果您想使用自定义错误,则必须自己提供(如果不这样,那么您可以在整个代码中使用变量而没有问题)。

特别是ErrorValue有一个需要指定的类型变量e:它在不使用CustomError构造函数的代码中无关紧要,但在translateError中确实很重要因为您正尝试在CustomError上进行模式匹配。看起来你想要的类型是TranslationId所以你想要

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