gpt4 book ai didi

haskell - ghc-7.8 中 `reads` 的歧义错误

转载 作者:行者123 更新时间:2023-12-01 07:56:44 24 4
gpt4 key购买 nike

我正在测试 Write yourself a Scheme in 48 hours 的代码使用 GHC-7.8.2,这给了我一个关于歧义的错误,我不记得在以前的 GHC 版本中遇到过。
摘录如下,并标记了问题行:

data LispVal = Atom String
| List [LispVal]
| DottedList [LispVal] LispVal
| Number Integer
| String String
| Bool Bool
unpackNum :: LispVal -> Integer
unpackNum (Number n) = n
unpackNum (String n) = let parsed = reads n in --problem line
if null parsed
then 0
else fst $ parsed !! 0
unpackNum (List [n]) = unpackNum n
unpackNum _ = 0

,错误说:
No instance for (Read a0) arising from a use of ¡®parsed¡¯
The type variable ¡®a0¡¯ is ambiguous
Note: there are several potential instances:
instance Read a => Read (Control.Applicative.ZipList a)
-- Defined in ¡®Control.Applicative¡¯
instance Read () -- Defined in ¡®GHC.Read¡¯
instance (Read a, Read b) => Read (a, b) -- Defined in ¡®GHC.Read¡¯
...plus 26 others

如果我将问题行更改为
unpackNum (String n) = let parsed = reads n ::[(Integer,String)] in 

然后一切正常。

我不明白为什么 GHC 无法从 unpackNum 的签名中推断出 ReadS 的类型.有人可以解释是什么触发了错误?

(

- 编辑 -

只是一些跟进。据我了解,函数类型 unpackNum :: LispVal -> Integer而事实是 fst $ parsed !! 0是它的返回值,它告诉 parsed有类型 [(Integer,b)] ,来自 type ReadS a = String -> [(a,String)] , parsed应该是 [(a, String)] .这两种不应该统一到 [(Integer, String)]并修复 parsed 的类型?

有人可以解释为什么 NoMonomorphismRestriction会打破上面的推理吗?

-- 编辑 2 --

从答案中,我可以理解如何 NoMonomorphismRestriction可能会导致这里的问题。不过,我不明白的是,这种“同一表达式的两种类型”行为如何与 Haskell 中的懒惰一致。在示例中 parsedreads n在一个块中是相同的表达式,应该只计算一次。怎么会有类型 a第一次评价和 Integer第二次?

)

谢谢,

最佳答案

如果 NoMonomorphismRestriction 会触发此事件活跃;顺便说一句,从 7.8 (see release notes, Section 1.5.2.3) 开始,GHCi 现在默认情况下就是这种情况。 .

如果禁用单态限制,则 parsed 的定义得到一个多态类型,即

parsed :: Read a => [(a, String)]

然后在 null parsed中第一次使用没有足够的上下文信息来解决什么 a是。

这恰好是单态限制实际上有好处的少数情况之一。因为对于多态类型,即使两个使用站点都有足够的类型
解决类约束的信息,实际解析将发生两次。

最好的解决方案仍然是使用 acomar 的答案中建议的模式匹配。

关于haskell - ghc-7.8 中 `reads` 的歧义错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23280939/

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