【发布时间】:2019-10-21 21:22:45
【问题描述】:
我正在通过阅读 Haskell Programming from First Principles, Allen & Moronuki 这本书来了解 Haskell。
在Monad Transformers, Functor & Applicative composition一章的练习中,要求读者为以下类型编写Bifunctor实例
data SemiDrei a b c = SemiDrei a
我的第一次尝试(编译)是
instance Bifunctor (SemiDrei a) where
bimap f g (SemiDrei a) = SemiDrei a
但是,看着它,在我看来,我应该能够写成bimap f g = id,因为最后一个参数没有改变,或者写成bimap f g x = x。两者都给了我编译错误,我希望有人能向我解释为什么我不能用这些更短的替代方法来表达bimap,即为什么我必须指定(SemiDrei a)。
我在 Haskell 8.6.5 上运行了这个(如果相关的话)
尝试:id
instance Bifunctor (SemiDrei a) where
bimap f g = id
-- compile error message:
• Couldn't match type ‘a1’ with ‘b’
‘a1’ is a rigid type variable bound by
the type signature for:
bimap :: forall a1 b c d.
(a1 -> b) -> (c -> d) -> SemiDrei a a1 c -> SemiDrei a b d
at src/Main.hs:69:5-9
‘b’ is a rigid type variable bound by
the type signature for:
bimap :: forall a1 b c d.
(a1 -> b) -> (c -> d) -> SemiDrei a a1 c -> SemiDrei a b d
at src/Main.hs:69:5-9
Expected type: SemiDrei a a1 c -> SemiDrei a b d
Actual type: SemiDrei a b d -> SemiDrei a b d
• In the expression: id
In an equation for ‘bimap’: bimap f g = id
In the instance declaration for ‘Bifunctor (SemiDrei a)’
• Relevant bindings include
f :: a1 -> b (bound at src/Main.hs:69:11)
bimap :: (a1 -> b) -> (c -> d) -> SemiDrei a a1 c -> SemiDrei a b d
(bound at src/Main.hs:69:5)
|
69 | bimap f g = id
| ^^
尝试:f g x = x
instance Bifunctor (SemiDrei a) where
bimap f g x = x
-- compile error message:
• Couldn't match type ‘a1’ with ‘b’
‘a1’ is a rigid type variable bound by
the type signature for:
bimap :: forall a1 b c d.
(a1 -> b) -> (c -> d) -> SemiDrei a a1 c -> SemiDrei a b d
at src/Main.hs:69:5-9
‘b’ is a rigid type variable bound by
the type signature for:
bimap :: forall a1 b c d.
(a1 -> b) -> (c -> d) -> SemiDrei a a1 c -> SemiDrei a b d
at src/Main.hs:69:5-9
Expected type: SemiDrei a b d
Actual type: SemiDrei a a1 c
• In the expression: x
In an equation for ‘bimap’: bimap f g x = x
In the instance declaration for ‘Bifunctor (SemiDrei a)’
• Relevant bindings include
x :: SemiDrei a a1 c (bound at src/Main.hs:69:15)
f :: a1 -> b (bound at src/Main.hs:69:11)
bimap :: (a1 -> b) -> (c -> d) -> SemiDrei a a1 c -> SemiDrei a b d
(bound at src/Main.hs:69:5)
|
69 | bimap f g x = x
| ^
【问题讨论】: