【问题标题】:Instance of Read class in HaskellHaskell 中 Read 类的实例
【发布时间】:2012-11-25 01:37:07
【问题描述】:

当我遇到困难时,我才刚刚开始玩 Haskell。

我正在尝试创建Read 类的新数据类型(我们称之为MyType)实例。 Mytype 是一个类型构造函数,所以它接受另一个类型作为参数。我想写这样的代码

    instance (Read a) => Read (MyType a) where
        readsPrec _ r = [foo (read r :: a ), r]

但它给了我以下错误

Could not deduce (Read a2) arising from a use of `read' from the context (Read a).

我认为既然 a 是 Readable 我可以推断它,但显然我错了。有什么想法吗?

编辑: 我把之前的代码改成了

readsPrec _ r = [foo (read r :: a ), ""]

所以如果我输入:read "myString" :: MyType a,它就可以正常工作。 现在我希望如果我在上下文中使用read "myString",我不应该指定要读取的类型。但问题在于

bar (read myString) a

bar:: MyType a -> a -> MyType a,我得到了 歧义变量类型

有没有可能做这样的事情而不会出现这种错误?

我希望现在更清楚了,我正在尝试简化代码,但我希望我没有遗漏任何重要的内容。

【问题讨论】:

  • 请在此处给出 foo 的类型,只是为了完整。
  • foo,它实际上是一个解析器,在我试图在这里简化的代码中它有点复杂。现在即使没有 ScopedTypeVariables 它实际上也可以编译,但正如你在另一篇文章中所说,我可能误解了 readPresc 的工作方式,因为现在我得到了 Exception: Prelude.read: no parse When I try to read a string as MyType.
  • 好的,所以在我的情况下正确应该是 [foo (read r :: a ), ""],希望对其他一些新手有帮助:)
  • 抱歉,我发现您的编辑令人困惑。你能把它改成一个问题吗?
  • 我改写一下,我希望现在更清楚:)

标签: haskell type-inference


【解决方案1】:

如果写成,代码实际上会进行类型检查

实例 (Read a) => Read (MyType a) 其中 readsPrec _ r = [(foo (读取 r),r)]

如果foo 的类型为a -> MyType a。编译器可以从readsPrec 的预期类型签名中找出对foo 的调用应该返回一个MyType a,因此(通过foo 的类型),表达式read r 应该具有类型a.

但是当你用 :: a 注释它时为什么它会失败?因为类型变量对于它们出现的类型签名是本地的。所以a 与实例头中的a 完全无关,而read r :: a 你实际上是在说:表达式read r 可以有任何任意类型。但是任意类型没有 Read 实例,因此出现错误消息。在消息中,编译器将内部 a 重命名为 a2 以避免名称冲突。

不过,如果您将 {-# LANGUAGE ScopedTypeVariables #-} 添加到模块标题中,您的代码可以按预期工作。现在,read r :: a 中的a 引用了实例头中a 的类型,一切顺利。

请注意,您没有正确使用 readsPrec,但我想这不是问题的一部分。

【讨论】:

  • 我添加了 ScopedTypeVariables 并且它实际上可以编译,但是当我尝试阅读时,我得到了 Exception: Prelude.read: no parse。您能否解释一下我没有正确使用 readsPrec 的事实是什么意思?我以为我只需要返回一个包含 1 个带有 MyType 元组和已解析字符串的列表,但显然我又错了。
  • 您不应返回已解析的字符串,而应返回尚未解析的字符串。此外,该列表应包含所有可能的字符串解析(如果有多个)和空列表(如果没有)(并且不是例外)。一般来说,如果你实现了readsPrec,你很有可能也应该使用readsPrec来代替a
猜你喜欢
  • 1970-01-01
  • 2015-05-30
  • 1970-01-01
  • 2016-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
相关资源
最近更新 更多