2012-05-08 7 views
4

私はライブラリとしてGHCを使用して、JavascriptコードジェネレータにHaskellを書いています。 Javascriptは整数型を持たず、そのNumber型は最大253までの整数しか表現できないため、整数をNumbersとして表現し、すべての算術演算を明示的に実行します。これは32ビットGHCではうまく動作しますが、64ビットバージョンではさらに悪くなります。Int32としてInt32を扱うように64ビットGHCに指示する方法はありますか?

GHCはInt64値をIntsに強く強制し、Int定数を64ビット値(0xffffffffは-1ではなく4294967295に変わります)と解釈し、それはあらゆる種類の厄介な問題を引き起こしています。

コンパイラは、標準ライブラリが32ビットマシン上に構築されていれば「通常の」ウェブの場合にはうまく機能しますが、「大量の数字は使用しないでください。あなたのコンパイラのマニュアルで見たいものではありません。 -O0でコンパイルすることで問題の一部(ただしすべてではない)を緩和することはできますが、遅いだけでなく大きすぎるコードも生成されます。

GHCがIntとInt64が同等であると仮定しないようにする必要があります。これも可能ですか?

+6

32ビット整数が必要な場合は、なぜ 'GHC.Int.Int32'を使用しないのですか? –

+0

これは確かに可能ですが、「Intが壊れているのでIntではなくInt32を使用する必要があります」は、コンパイラのマニュアルでも見たいものではありません。 – valderman

+1

「Int」について何が約束されたのですか? –

答えて

7

32ビットGHCを使用しないと、これは不可能です。あなたがInt種類について知っている唯一のことは、それが

少なくとも範囲を有していることである

Haskell Language standard says [-2^29。2^29-1

ですから、これより幸いにIntの値を切り捨てることができ、依然として完全に準拠したHaskell 2010実装です!

しかし、おそらくこれを行うべきではなく、JavaScriptの64ビット整数型を探してください。例えばと同じトリック。 GHCは、32ビットマシンでInt64をサポートします。

+0

GoogleのClosureライブラリからLongクラスのようなものを64ビットタイプに切り換えると、しかし、コードサイズを爆破し、絶対にパフォーマンスを殺すだろう。これは大多数のコードが32ビットでかなり満足しているときに支払う多額の価格のようだ。 Int値を切り捨てるのははるかに魅力的な選択肢ですが、GHCはInt64値をIntに強制しているため(実際にInt64を使用するコードを破損する可能性があります) – valderman

+1

それはJavaScriptです - とにかくパフォーマンスはどれくらい良いでしょうか。私はむしろそれをゆっくりと正しいものにしたいと思っています。 –

+0

パフォーマンスが必ずしも低下するとは限りません。 GHCの 'Int'サイズの整数型でのパフォーマンスは、' Int'を直接使うこととほぼ同じです。なぜ、同等のJavascriptライブラリで同じことができないのですか?私はまだあなたが 'Int32'を使うべきだと思っています。 –

1

JavaScriptの数値は2倍で表されるため、Doubleを使用してください。

3

「Int」は、2^29が十分に大きいものにのみ使用され、それ以外は問題ではありません。それ以外の場合はIntegerまたはData.WordまたはData.Int(Int8、Int16など)のいずれかの型を使用します。良い例には、ほとんどのサイズと数が含まれます(ただし最近のファイルサイズは2^32を簡単に超えることはできません)。

クラシックの悪い例:Control.Concurrent.threadDelay :: Int - > IO()。引数はuSecの休止時間です。 2^29マイクロ秒= 8.94784853分(Google電卓によると)。引数は整数、または少なくともWord64(584 554.531年)でなければなりません。

関連する問題