Попытка реализовать Data.Either - PullRequest
12 голосов
/ 19 августа 2011

Чтобы помочь мне выучить аппликативные функторы и функторы, я подумал, что было бы неплохо увидеть, как Either реализован с классами типов Functor и Applicative.Очевидно, что я мог бы просто пойти дальше и прочитать код, но я считаю, что более полезно попробовать и реализовать что-то самостоятельно, чтобы лучше понять вещи.

К вашему сведению Я пытаюсь реализовать версию результатов Haskell для Haskell.эта презентация http://applicative -errors-scala.googlecode.com / svn / artifacts / 0.6 / chunk-html / index.html

В любом случае, это то, что у меня есть до сих пор

 data Validation a b = Success a | Failure b deriving (Show, Eq)

 instance Functor (Validation a) where
     fmap f (Failure x) = Failure x
     fmap f (Success x) = Success (f x)

Но всякий раз, когда я пытаюсь запустить это с ghci, я просто получаю следующее сообщение об ошибке: -

[1 of 1] Compiling Main             ( t.hs, interpreted )

t.hs:5:35:
    Couldn't match type `b' with `a1'
      `b' is a rigid type variable bound by
          the type signature for
            fmap :: (a1 -> b) -> Validation a a1 -> Validation a b
          at t.hs:4:5
      `a1' is a rigid type variable bound by
           the type signature for
             fmap :: (a1 -> b) -> Validation a a1 -> Validation a b
           at t.hs:4:5
    Expected type: a
      Actual type: b
    In the return type of a call of `f'
    In the first argument of `Success', namely `(f x)'
    In the expression: Success (f x)

t.hs:5:37:
    Couldn't match type `a' with `a1'
      `a' is a rigid type variable bound by
          the instance declaration at t.hs:3:30
      `a1' is a rigid type variable bound by
           the type signature for
             fmap :: (a1 -> b) -> Validation a a1 -> Validation a b
           at t.hs:4:5
    In the first argument of `f', namely `x'
    In the first argument of `Success', namely `(f x)'
    In the expression: Success

Я не совсем уверен, почему это так, кто-нибудь может помочь?

1 Ответ

13 голосов
/ 19 августа 2011

Вы пытаетесь заставить экземпляр Functor работать на части Success, что является обычным делом, но из-за порядка параметров вашего типа он определяется для типа в Failure часть вместо.

Так как вы определили его как

data Validation a b = Success a | Failure b

instance Functor (Validation a) where
    ...

Это означает, что ваша реализация fmap должна иметь тип (x -> y) -> Validation a x -> Validation a y. Но поскольку переменная второго типа относится к случаю Failure, это не проверка типа.

Вы хотите, чтобы переменная типа для случая Success была последней:

data Validation b a = Success a | Failure b
...