Here's Either a的标准函数器实例
instance Functor (Either a) where
fmap _ (Left x) = Left x
fmap f (Right y) = Right (f y)当加载到GHCi中时,添加as-pattern会导致编译错误:
instance Functor (Either a) where
fmap _ z@(Left x) = z -- <-- here's the as-pattern
fmap f (Right y) = Right (f y)
Couldn't match expected type `b' against inferred type `a1'
`b' is a rigid type variable bound by
the type signature for `fmap' at <no location info>
`a1' is a rigid type variable bound by
the type signature for `fmap' at <no location info>
Expected type: Either a b
Inferred type: Either a a1
In the expression: z
In the definition of `fmap': fmap _ (z@(Left x)) = z为什么这个不起作用?
发布于 2012-08-21 21:57:30
fmap具有签名(a -> b) -> f a -> f b,即它必须允许a和b不同。在您的实现中,a和b只能相同,因为它返回的内容与作为参数传递的内容相同。所以GHC抱怨说。
发布于 2012-08-21 21:58:29
我最好的猜测是这是失败的,因为z在等式的每一端代表不同的类型:
整体类型为fmap :: (a -> b) -> Either t a -> Either t b
z :: Either t b,
似乎允许Left x在同一等式中有多个不同的类型,但z不允许。
这个实现也失败了,显然是出于同样的原因:
instance Functor (Either a) where
fmap f (Right y) = Right (f y)
fmap _ z = z
Couldn't match expected type `b' against inferred type `a1'
`b' is a rigid type variable bound by
the type signature for `fmap' at <no location info>
`a1' is a rigid type variable bound by
the type signature for `fmap' at <no location info>
Expected type: Either a b
Inferred type: Either a a1
In the expression: z
In the definition of `fmap': fmap _ z = z发布于 2012-08-22 03:24:00
如果您将fmap的签名专门化为Either l,则会得到:
fmap :: (a -> b) -> Either l a -> Either l b这意味着在case语句左侧进行模式匹配的Left r必须具有Either l a类型。但是,您不能按原样返回它,因为您必须返回Either l b。这需要将左边的值重新包装在一个新的Left中,以便编译器可以推断它返回的是一个新生成的Either,该Right值可能具有不同的类型。
https://stackoverflow.com/questions/12056257
复制相似问题