我正在使用GHC作为库编写Haskell到Javascript代码生成器。由于Javascript没有整数类型,并且其Number类型只能正确表示高达2⁵3的整数,我将整数表示为数字,明确地执行所有算术模2¾。这对于32位GHC非常有效,但对于64位版本则更差。
GHC很乐意将Int64值强制转换为Ints,并将Int常量解释为64位值(例如,0xffffffff变为4294967295而不是-1),这会导致各种恼人的问题。
即使在64位系统上,编译器也能很好地处理“普通”Web内容,前提是标准库是在32位机器上构建的,但“请不要使用大数字,好吗?”不是你想在编译器手册中看到的东西。一些问题(但不是全部)可以通过使用-O0进行编译来缓解,但是(不出所料)产生的代码不仅速度慢,而且太大。
所以,我需要阻止GHC假设Int和Int64是等价的。这甚至可能吗?
答案 0 :(得分:7)
如果不使用32位GHC,这是不可能的。
Haskell Language standard says您对Int
类型唯一了解的是
至少范围[-2 ^ 29 .. 2 ^ 29-1
因此,您可以愉快地截断大于此值的Int
值,并且仍然是完全符合Haskell 2010的实现!
但是,您可能不应该这样做,而是为JavaScript寻找64位整数类型。与例如同样的技巧GHC支持32位计算机上的Int64
。
答案 1 :(得分:3)
通常情况下,“Int”应仅用于2 ^ 29足够大的事物,除此之外无关紧要。其他任何地方都使用Integer或Data.Word或Data.Int(Int8,Int16等)类型之一。很好的例子包括大多数尺寸和数量(但不是文件大小,这些天很容易超过2 ^ 32)
经典坏示例:Control.Concurrent.threadDelay :: Int - > IO()。参数是uSec中的暂停时间。 2 ^ 29 uSec = 8.94784853分钟(根据谷歌计算器)。参数应该是Integer,或者至少是Word64(584 554.531年)。
答案 2 :(得分:1)
Javascript数字表示为双精度数,因此请使用Double
。