私は、次のHaskellのコードを持っている:'**'の使用に起因する(浮動整数)のインスタンスはありませんか?
two :: Integer -> Integer
two i = toInteger(2 ** i)
は、なぜそれが機能していませんか?代わりに
私は、次のHaskellのコードを持っている:'**'の使用に起因する(浮動整数)のインスタンスはありませんか?
two :: Integer -> Integer
two i = toInteger(2 ** i)
は、なぜそれが機能していませんか?代わりに
使用^
:
two i = 2^i
そしてインテグラル型に戻って結果をキャストするための必要はありません。一方
(**) :: Floating a => a -> a -> a
toInteger
本質的に一体化された入力を必要とする:
(**)
関数シグネチャに基づいて、浮動小数点入力を必要と
toInteger :: Integral a => a -> Integer
したがって、次の2つの調整ができませんあなたがそれを使う方法。とにかく整数入力を期待しているように見えるので、それは、あなたがそうのように、代わりに(^)
を使用して検討するかもしれない、と述べた:@leftaroundaboutが正しくコメントで指摘し
two :: Integer -> Integer
two i = 2^i
として、(^)
はi
の負の値のために失敗します。これは、値をチェックし、別の方法で処理することによって解決することができ、このような何か:ので、あなたの「この...
two :: Integer -> Integer
two i = toInteger(2 ** i)
...は動作しません
two :: Integer -> Integer
two i = if i > 0 then 2^i else floor (2 ** fromIntegral i)
理由がありますi
が整数であることを宣言しまして、私たちは(**)
...
Prelude> :t (**)
(**) :: Floating a => a -> a -> a
の種類を見れば...そのすべての引数は同じタイプのものであり、その型がTのインスタンスである必要があります彼はFloating
タイプクラスです。 Integer
はFloating
のインスタンスではありません。これは「浮動整数」の意味ではありません。
最も簡単な解決策は、ErikRが示唆するように^
を使用することです。それは整数を整数に上げる。
(^) :: (Integral b, Num a) => a -> b -> a
**
をもう少し学びたい場合は、お読みください。
したがって、整数をFloating
のインスタンスであるタイプに変換する必要があります。 fromIntegral
でこれを行うことができます。これを行うと、さまざまなタイプがあいまいであるというエラーメッセージが表示されます。これらは最初のメッセージほど明瞭ではありませんが、問題はtoInteger
の使用です。このタイプを見れば明らかになります。
Prelude> :t toInteger
toInteger :: Integral a => a -> Integer
Integral
、ではない私たちはtoInteger
に**
の結果を渡している、そしてそれはFloating
あるので、toInteger
は間違っ機能です。 round
が良い選択です。
two :: Integer -> Integer
two i = round(2 ** fromIntegral(i))
これで機能します。
注意しなければならないのは、 '^'は非負の指数にしか作用しないということです。 'floor(2 ** fromIntegral i)'のようにゼロへの丸めが必要な場合は、負の 'i'を与えます。これは余分な節で処理する必要があります。 – leftaroundabout
@leftaroundaboutありがとうございました。私はそれを私の答えに加えてもいいですか? –
もちろん、そうではありません。 – leftaroundabout