B a where bar :: a bar -6ren">
gpt4 book ai didi

haskell - 类型类默认值中的类型注释会导致 "could not deduce"类型错误

转载 作者:行者123 更新时间:2023-12-04 22:15:09 26 4
gpt4 key购买 nike

这是初学者的问题,但我无法在任何地方识别出任何答案。
以下代码:

class A a where
foo :: a
class A a => B a where
bar :: a
bar = (foo :: a)

无法在 GHC 中编译,并显示错误消息:
Could not deduce (A a1) arising from a use of `foo'
from the context (B a)
bound by the class declaration for `B'
...

GHC 似乎不相信类型类 B 定义中的所有 a 都是相同的。谁能解释一下它的推理路线是什么?

删除第 5 行中的类型注释当然避免了这个问题,但我仍然想了解这里发生了什么......

最佳答案

您确实应该摆脱类型注释。类型变量在 Haskell 中没有作用域,所以 (foo :: a) 。被解释为“让 foo 为任何类型的 a 生成一个 a 类型的值”,这不能完成,因为 foo 只会生成 a 类中的那些类型 A 的值。

换句话说,您的 B 声明等效于

class A a => B a where
bar :: a
bar = (foo :: c)

也就是说,类型变量 a 的使用与声明中的其他使用之间没有联系。

删除显式注释可以解决您的问题:
class A a => B a where
bar :: a
bar = foo

现在,编译器可以确定您要调用 foo 的类型,即您在 a 的签名中编写的类型 bar 并且出现在类声明的头部。

Glasgow Haskell Compiler (GHC) 带有一个允许作用域类型变量的扩展。启用该扩展后,您的片段将按照您最初的预期进行类型检查:
{-# LANGUAGE ScopedTypeVariables #-}
class A a where
foo :: a
class A a => B a where
bar :: a
bar = (foo :: a)

关于haskell - 类型类默认值中的类型注释会导致 "could not deduce"类型错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10243942/

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