gpt4 book ai didi

haskell - Haskell 中不完整的隐式类型推断

转载 作者:行者123 更新时间:2023-12-02 21:05:55 25 4
gpt4 key购买 nike

让我们考虑以下示例:

data A = A{x::Int} deriving(Show)

instance Func_f (A -> String) where
f _ = "ala"

class Func_f a where
f :: a

main :: IO ()
main = do
let
a = A 5
x = f a
print 5

使用ghc -XFlexibleInstances main.hs编译

(我已经尝试过-XExtendedDefaultRules,但没有任何进展)

为什么编译时会出现错误?:

main.hs:25:21:
No instance for (Func_f (A -> t0)) arising from a use of `f'
The type variable `t0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there is a potential instance available:
instance Func_f (A -> String) -- Defined at main.hs:7:10
Possible fix: add an instance declaration for (Func_f (A -> t0))
In the expression: f a
In an equation for `x': x = f a
In the expression:
do { let a = A 5
x = f a;
print 5 }

Func_f 只有一个实例,因此 Haskell 应该能够知道 x = f a 的结果。您可以通过手动提供类型来修复错误,如下所示:x = f a::String,但这不适合我的情况,因为我正在生成 Haskell 代码,并且我会喜欢 Haskell 的输入 inferencer 来帮我完成这项工作。

最佳答案

您遇到了open world assumption 。基本思想是 GHC 始终假设您可以向代码中添加更多类实例。此外,您无法控制实例在模块之间导出和导入的方式。因此,仅依赖特定类的一个实例是行不通的,并且会导致奇怪的错误。

本质上,没有什么可以阻止你——或者任何其他人,就此而言——编写另一个实例,例如:

 instance Func_f (A -> Int) where
f _ = 10

然后就不可能弄清楚你想要在代码中使用哪一个。这可能会导致您的代码仅因链接到另一个模块而中断!

但是,如果您实际使用该值,它的类型很可能会受到其他参数的约束,并且歧义性就会消失。例如,以下作品:

main :: IO ()
main = do
let a = A 5
x = f a
putStr x

基本上,这是其中一种情况(类似于 read .show),由于 GHC 处理类型类实例的方式,类型签名是不可避免的。

关于haskell - Haskell 中不完整的隐式类型推断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17658239/

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