试图实现Data.Either

djh*_*rld 12 haskell functor either

为了帮助我学习Applicative Functors和Functors,我认为看看如何Either用类型类Functor和函数实现它会很有趣Applicative.显然我可以继续阅读代码,但我发现自己尝试实现一些东西以更好地理解事物更有用.

仅供参考我正在尝试实现此演示文稿结果的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)
Run Code Online (Sandbox Code Playgroud)

但每当我尝试运行此命令时,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
Run Code Online (Sandbox Code Playgroud)

我不确定为什么会这样,有人可以帮忙吗?

ham*_*mar 13

您正在尝试使Functor实例在Success部件上工作,这是正常的事情,但由于您的类型参数的顺序,它正在Failure部件中的类型上定义.

因为你已经将其定义为

data Validation a b = Success a | Failure b

instance Functor (Validation a) where
    ...
Run Code Online (Sandbox Code Playgroud)

这意味着您的实现fmap应具有该类型(x -> y) -> Validation a x -> Validation a y.但由于第二个类型变量适用于该Failure情况,因此不进行类型检查.

您希望Success案例的类型变量是最后一个:

data Validation b a = Success a | Failure b
Run Code Online (Sandbox Code Playgroud)

  • @djhworld:现在你也明白为什么,在'ab`中,`Left`代表失败的情况(不仅仅因为它不是"正确的"结果). (5认同)