haskell:read不解析没有显式类型的浮点数

muf*_*fel 4 haskell

考虑以下功能

add1 :: Num a => a -> a
add1 x = x + 1
Run Code Online (Sandbox Code Playgroud)

以及以下申请

*Main> add1 2
3
*Main> add1 2.2
3.2
*Main> add1 (read "1")
2
add1 (read "1.5"::Float)
2.5
*Main> add1 (read "1.5")
*** Exception: Prelude.read: no parse
Run Code Online (Sandbox Code Playgroud)

为什么最后一次请求add1失败的浮点数,而它适用于整数?为什么我必须在那种情况下指定类型?

chi*_*chi 8

GHCi给它类型

> :t add1 (read "1.5")
add1 (read "1.5") :: (Read a, Num a) => a
Run Code Online (Sandbox Code Playgroud)

所以,它仍然是多态的.但是,当在GHCi中进行评估时,它会隐式print编辑,因此GHCi必须选择一些具体的类型a.GHCi使用默认规则,并静态选择a = Integer.请注意,此选择是静态完成的(大致在类型检查期间),并且仅取决于类型(例如String),而不是实际值(例如"1.5").Integer既是a Read又是a Num,所以所有的静态检查都通过了.

更具体地,GHCI尝试类型(),Integer,Double-的顺序,除非有一个default声明说,否则.

然后,在运行时代码表现为

> add1 (read "1.5") :: Integer
*** Exception: Prelude.read: no parse
Run Code Online (Sandbox Code Playgroud)

因为字符串无法解析.相比之下,这很好:

> add1 (read "1.5") :: Float
2.5
Run Code Online (Sandbox Code Playgroud)

  • 我认为一个关键点是静态推断/选择类型,并且不依赖于字符串.另外,我认为这个默认规则实际上是标准的. (3认同)