Haskell只是使用read函数发出错误信号

Haskell只是使用read函数发出错误信号,haskell,Haskell,谁能解释一下,为什么读一个数字加上另一个数字是有效的,尽管读一个数字是无效的 Prelude> read "5" + 3 8 Prelude> read "5" :33:1: No instance for (Read a0) arising from a use of `read' The type variable `a0' is ambiguous Possible fix: add a type signature that fixes these type v

谁能解释一下,为什么读一个数字加上另一个数字是有效的,尽管读一个数字是无效的

Prelude> read "5" + 3 8 Prelude> read "5" :33:1: No instance for (Read a0) arising from a use of `read' The type variable `a0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there are several potential instances: instance Read () -- Defined in `GHC.Read' instance (Read a, Read b) => Read (a, b) -- Defined in `GHC.Read' instance (Read a, Read b, Read c) => Read (a, b, c) -- Defined in `GHC.Read' ...plus 25 others In the expression: read "5" In an equation for `it': it = read "5" 为什么5不明确?

5本身并不含糊,更重要的是Haskell不知道你想读哪种类型。read是一个定义为以下内容的函数:

read :: Read a => String -> a
然后定义一个实例Read WeirdNumbers,将5映射到5,等等。现在5映射到几个类型

你可以简单地告诉Haskell你想读哪种类型的书来解决这个问题。比如:

Prelude> read "5" :: Int
5
Prelude> read "5" :: Float
5.0
顺便说一下,Read5+3之所以有效,是因为这里提供了3和a+::Num a=>a->a->a。所以Haskell认为Well 3是一个整数,+要求左操作数和右操作数的类型相同,我知道我必须使用read,这样它也能读入整数。

5本身并不含糊不清,更重要的是Haskell不知道要读入什么类型。read是一个定义为以下内容的函数:

read :: Read a => String -> a
然后定义一个实例Read WeirdNumbers,将5映射到5,等等。现在5映射到几个类型

你可以简单地告诉Haskell你想读哪种类型的书来解决这个问题。比如:

Prelude> read "5" :: Int
5
Prelude> read "5" :: Float
5.0

顺便说一下,Read5+3之所以有效,是因为这里提供了3和a+::Num a=>a->a->a。Haskell认为井3是一个整数,+要求左操作数和右操作数是同一类型的,我知道我必须使用read,这样它也能读入整数。

有趣的是,它的实际签名更复杂、更有趣,虽然对于问题的范围来说,它并不相关。@bereal在Haskell中,类型签名几乎总是非常相关的。但是read在我看来是一个特别有趣的例子,因为它是我遇到的返回类型推断最常见的用法之一,返回类型推断不依赖于输入的类型。@bereal如果read有类型签名字符串->Int,那么操作代码就不会有任何问题。看起来问题的关键确实是read在输出类型中是多态的。我不知道如果不提到一般类型,如何解释这个问题,除非只提到快速修复添加注释,而不解释为什么需要添加注释。@chi@Matthew我的意思是,实际上read::String->a不是读取a的方法,但Read a是根据readsPrec::Int->ReadS a等定义的。如果我没有说清楚,很抱歉。有趣的是,的实际签名更复杂、更有趣,尽管对于问题的范围来说,它并不相关。@bereal在Haskell中,类型签名几乎总是非常相关的。但是read在我看来是一个特别有趣的例子,因为它是我遇到的返回类型推断最常见的用法之一,返回类型推断不依赖于输入的类型。@bereal如果read有类型签名字符串->Int,那么操作代码就不会有任何问题。看起来问题的关键确实是read在输出类型中是多态的。我不知道如果不提到一般类型,如何解释这个问题,除非只提到快速修复添加注释,而不解释为什么需要添加注释。@chi@Matthew我的意思是,实际上read::String->a不是读取a的方法,但是ReadA是根据readsPrec::Int->ReadS a等定义的。如果我没有说清楚,很抱歉。