2012-05-08 58 views
4

我正在寫一個Haskell到Javascript代碼生成器,使用GHC作爲庫。由於Javascript沒有整數類型,它的Number類型只能正確表示整數2 3 3,我將整數表示爲Numbers,顯式地執行所有算術模2 2。這對於32位GHC非常有效,但對於64位版本則更糟糕。有什麼辦法可以告訴64位GHC將Int視爲Int32?

GHC會很高興地將Int64值強制轉換爲Ints並將Int常量解釋爲64位值(例如,0xffffffff變成4294967295而不是-1),這會導致各種煩人的問題。

即使在64位系統上,即使標準庫建立在32位機器上,「編譯器」也能很好地工作,但「請不要使用大數字,好嗎?」不是你想在編譯器手冊中看到的東西。一些問題(但不是全部)可以通過編譯-O0來緩解,但是(不出所料)產生的代碼不僅很慢,而且還太大。

因此,我需要阻止GHC假設Int和Int64是等價的。這甚至有可能嗎?

+6

如果你想要32位整數,爲什麼不使用'GHC.Int.Int32'? –

+0

這確實是可能的,但是「您必須使用Int32而不是Int,因爲Int被破壞」並不是您希望在編譯器手冊中看到的東西。 – valderman

+1

「Int」有什麼承諾被破壞了? –

回答

7

這是不可能的,不使用32位GHC。

Haskell Language standard says,你知道的Int類型的唯一的事情是,它有

至少在區間[-2^29。2^29-1

所以你可以愉快地截斷大於這個值的Int值,並且仍然是完全符合Haskell 2010實現的!

但是,您可能不應該這樣做,而應該爲JavaScript查找64位整數類型。與例如相同的技巧GHC確實在32位機器上支持Int64

+0

將所有內容切換到64位類型,比如Google的Closure庫中的Long類,確實可以解決問題,但會炸燬代碼大小和絕對謀殺的性能;當絕大多數代碼對32位非常滿意時,這似乎是一個巨大的代價。 截斷Int值是一個非常有吸引力的選擇,但由於GHC看起來強迫Int64值到Int(即使這些值是顯式類型的),這可能會破壞實際使用Int64的任何代碼。 – valderman

+1

這是JavaScript - 無論如何,表現會有多好。我寧願讓它緩慢和正確,而不是默默無聞的數字。 –

+0

這不一定會損害性能。 GHC的'Int'大小的'Integer'的性能幾乎等同於直接使用'Int',爲什麼同樣的Javascript庫不能做到這一點?儘管我仍然認爲你應該使用'Int32'。 –

1

Javascript編號表示爲雙打,因此請使用Double

3

作爲一個規則,「詮釋」只能用於2^29足夠大的事物,除此之外無關緊要。其他地方使用Integer或Data.Word或Data.Int(Int8,Int16等)類型之一。很好的例子包括大多數大小和數量(但不是文件大小,這些天可以輕鬆超過2^32)

經典的壞例子:Control.Concurrent.threadDelay :: Int - > IO()。該參數是以uSec爲單位的暫停時間。 2^29 uSec = 8.94784853分鐘(根據谷歌計算器)。爭論應該是整數,或者至少是Word64(584 554.531年)。

相關問題