我开始学习Haskell,我不明白会发生什么:我有一个非常简单的代码:
import System.IO
import Control.Monad
fact n = product [1..n]
main :: IO ()
main = do
input_line <- getLine
let m = read input_line :: Int
print (fact m)
return ()
Run Code Online (Sandbox Code Playgroud)
在ghci,当我尝试
*Main> :load "fact.hs"
[1 of 1] Compiling Main ( fact.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
4500
0
Run Code Online (Sandbox Code Playgroud)
但
*Main> fact 4500
2274299510944531831673.....
Run Code Online (Sandbox Code Playgroud)
我错过了什么?谢谢你的任何解释.
类型fact
是Num a => a -> a
.在你的main
,你正在应用它m
,你声明是一个Int
.所以结果fact
将是一个,Int
并且之间的所有计算将使用Int
s 完成.Int
s是固定宽度的整数,不能表示大的数字,导致溢出,从而导致错误的结果.
关于你的第二次尝试,你申请fact
到4500
不指定你想要的类型4500
来定.在这种情况下,Haskell使用默认的数字类型,即Integer
.与之不同Int
,Integer
可以表示任何大小的整数,因此代码可以正常工作.
如果你这样做fact 4500 :: Int
,你会得到与第一次相同的错误结果.同样,如果你用:: Integer
你的main
,而不是Int
(或将其关闭,所以默认使用again¹),你会得到正确的结果.
¹请注意,这会产生警告.在GHCi或小型测试程序之外,通常优先明确注释类型而不是依赖于默认规则.