考虑以下功能
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失败的浮点数,而它适用于整数?为什么我必须在那种情况下指定类型?
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)