2017-01-01 44 views
1
匹配的多態型

我用榆樹形式: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 

我想出了一個解決方案,但它看起來奇怪,我不知道這是否是正確的​​:

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

那是因爲你沒有指定什麼'e'是'translateError:ErrorValueé - > String' - 所以它不知道任何有關它。可能傳入'e - > String'函數? – Reactormonk

回答

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 
+0

我這樣做,然後我從[這裏](https://github.com/werner/madison-elm/blob/master/src/elm/ViewHelpers.elm#L32)調用它,然後我改變了類型簽名:'errorFor:FieldState TranslationId String - > Html msg',然後我從[這裏]得到一個錯誤(https://github.com/werner/madison-elm/blob/master/src/elm/ViewHelpers.elm#L25 ),最後我被卡住了。 –

+1

我試過讓我的答案更完整一點,但建議是一樣的 –

+0

是的,我很感激你花時間檢查了這一點。然而,也許我沒有足夠的解釋,按照你的建議,我得到這個[點](https://github.com/werner/madison-elm/blob/master/src/elm/ViewHelpers.elm#L25),它從elm-form包中調用一個函數getFieldAsString,就像你在這裏看到的一樣(https://github.com/etaque/elm-form/blob/3e97913dab84f2fb5432379664a9f578d4158f48/src/Form.elm#L92),它期望一種形式:'FieldState e String',但是我傳遞:'FieldState TranslationId String',這會產生錯誤。 –