バイナリログ(ログベース2)に基づいて計算を計算するために書いたコードで、奇妙なエラーが見つかりました。ここで、正の整数のバイナリ対数計算lb
ためのコードである:2の累乗で予期しない動作が発生する
lb :: Int -> Maybe Int -- Binary logarithm, rounded down
lb 1 = Just 0
lb x
| 1 < x = (+1) <$> lb (div x 2)
| otherwise = Nothing
ここ
それはlb (2^31)
が何らかの形で失敗したと思われるエラーは、次の注釈付きGHCiの出力
λ: lb (2^30)
Just 30
λ: lb (2^31) -- should be Just 31
Nothing
λ: 1 < 2^31 -- smoke check, lb's first guard evaluates to True
True
λ: lb (div (2^31) 2) == lb (2^30) -- smoke check, these should be equal
False
λ: div (2^31) 2 == 2^30 -- smoke check, these are indeed equal
True
に示されているように、あります最初のガードは、otherwise
の式につながっていますが、私はその理由を一貫して説明できません。
さらに、表現div (2^31) 2
は何とかInt
Integer
からlb
'Int'を' Integer'に切り替えようとしましたか?私はおそらくアンダーフローの問題があると思う。そして、私はデフォルトが 'Integer'だと思いますので、3番目のラムダはうまくいくはずです... – Dair
ああ、テスト値を型制約するのを忘れました。うん、それはそれを解決する必要があります。 –