Haskell中没有错误消息

NoB*_*ugs 1 error-handling haskell

出于好奇,我制作了一个简单的脚本来检查在Haskell中构建列表的速度和内存效率:

wasteMem :: Int -> [Int]
wasteMem 0 = [199]
wasteMem x = (12432483483467856487256348746328761:wasteMem (x-1))

main = do
    putStrLn("hello")
    putStrLn(show (wasteMem 10000000000000000000000000000000000))
Run Code Online (Sandbox Code Playgroud)

奇怪的是,当我尝试这个时,它没有耗尽内存或堆栈空间,它只打印[199],就像运行wasteMem 0一样.它甚至没有打印错误消息......为什么?在ghci中输入这个大数字只是打印数字,所以我不认为这是一个舍入或读取错误.

Tho*_*son 15

您的程序使用的数字大于maxBound :: Int32.这意味着它在不同平台上的行为会有所不同.对于GHC,x86_64 Int是64位(否则为32位,但Haskell报告仅承诺29位).这意味着您的荒谬大值(1x10 ^ 34)代表4003012203950112768我,零32位的人代表:

GHCI> 10000000000000000000000000000000000 :: Int
4003012203950112768
GHCI> 10000000000000000000000000000000000 :: Data.Int.Int32
0
Run Code Online (Sandbox Code Playgroud)

这可以通过使用固定大小类型(例如:来自Data.Word或Data.Int)或使用Integer来使平台独立.

总而言之,这是一个开始时考虑不周的测试.Haskell是懒惰的,因此wastedMem n任何值n所消耗的内存量都是最小的 - 它只是一个thunk.一旦你试图显示这个结果,它将一次一个地从列表中获取元素 - 首先生成"[12432483483467856487256348746328761,并将列表的其余部分作为thunk.在第二个值被考虑之前,可以对第一个值进行垃圾收集(恒定空间程序).