gpt4 book ai didi

haskell - Bifunctor 实例定义上的类型签名不匹配

转载 作者:行者123 更新时间:2023-12-02 02:52:23 26 4
gpt4 key购买 nike

我正在通过阅读本书来了解 Haskell Haskell Programming from First Principles, Allen & Moronuki .

在 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
| ^

最佳答案

事实上,最后一个参数并没有保持不变:它的类型发生了变化。输入是 SemiDrei a x y输出为 SemiDrei a p q ,其中 f :: x -> pg :: y -> q .

这意味着您必须解构原始类型的值并重建新类型的值,这就是您在原始实现中所做的。

但是您的直觉是正确的:这两个值确实具有相同的内存表示。而 GHC 可以推导出这个事实,当它推导出来时,它会自动解决一个 Coercible 对您的约束,这意味着您可以使用 coerce将一个转换为另一个的函数:

 bimap _ _ = coerce

关于haskell - Bifunctor 实例定义上的类型签名不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58494308/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com