为了帮助我学习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)
但每当我尝试使用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
我不确定为什么会这样,有人可以帮忙吗?
答案 0 :(得分:13)
您正试图让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