2011-09-08 6 views
4

以下は、2147483647が素数であるため、Trueを返します。なぜこのハスケルは、拡張されたときにあいまいなタイプについて文句を言うのですか?

length [f | f <- [2..(floor(sqrt 2147483647))], 2147483647 `mod` f == 0 ] == 0 

なぜ私は以下のように拡張しようとしないのですか?

Prelude> [n | n <- [2..], length [f | f <- [2..(floor(sqrt n))], n `mod` f == 0 ] == 0 ] 

<interactive>:1:39: 
    Ambiguous type variable `t' in the constraints: 
     `RealFrac t' arising from a use of `floor' at <interactive>:1:39-51 
     `Integral t' arising from a use of `mod' at <interactive>:1:56-64 
     `Floating t' arising from a use of `sqrt' at <interactive>:1:45-50 
    Probable fix: add a type signature that fixes these type variable(s) 

私は理解できませんが、なぜRealFracは床の使用から生じるのですか?私はフロアがRealFracsを取ってIntegralsを生産したと思った?さらに、上の例では不平を言っていませんでした。

Prelude> :t floor 
floor :: (RealFrac a, Integral b) => a -> b 

答えて

10

ましょう少しこれを非難読化:

Prelude> (\x -> x `mod` (floor . sqrt) x) 2 

<interactive>:1:24: 
    Ambiguous type variable `b' in the constraints: 
     `Floating b' arising from a use of `sqrt' at <interactive>:1:24-27 
     `Integral b' arising from a use of `mod' at <interactive>:1:7-30 
     `RealFrac b' arising from a use of `floor' at <interactive>:1:16-20 
    Probable fix: add a type signature that fixes these type variable(s) 

あなたはsqrtfloorに渡す、floatとしてnの値を使用しています。その結果をintとして使用し、その結果をmodに渡します。コンパイラは、これらすべてのインスタンスを持つ型の名前を付けることはできません。

それはあなたが二つの異なる数値リテラルを使用しているので、あなたの最初の例では、他の言葉で

Prelude> 2 `mod` (floor . sqrt) 2 
0 

がある作品な理由。 1つはintになり、もう1つはfloatになります。両方に同じ値を使用している場合は、fromIntegralにコールしてintをfloatに変換する必要があります。

あなたは、型シグネチャを追加[2..] :: [Integer][2..]を変更することにより、別のエラーメッセージを取得することができます。

No instance for (RealFrac Integer) 
    arising from a use of `floor' at <interactive>:1:52-64 
No instance for (Floating Integer) 
    arising from a use of `sqrt' at <interactive>:1:58-63 

これは、それがより明確に2つの異なるタイプとしてnの値を使用していることになるかもしれません。

-1

としては、私の答えはあなたが作るリストは以来Floatingの任意のインスタンスで構成することができますので、私の知る限り見ることができるように、それはだ

正しい:-)ないが、以下のCAマッキャンが指摘

0123: sqrtの型シグネチャは fromIntegral :: (Integral a, Num b) => a -> bsqrtをプリコンポーズすることにより

sqrt :: Floating a => a -> a 

である、あなたは望ましい結果を得ます

Prelude> take 10 $ [n | n <- [2..], length [f | f <- [2..(floor(sqrt (fromIntegral n)))], n `mod` f == 0 ] == 0 ] 
[2,3,5,7,11,13,17,19,23,29] 
+2

ハスケルのデフォルトのメカニズムは、一般的にそのようなあいまいさを処理します。例えば、「Floating」のインスタンスは、通常は「Double」にデフォルト設定されます。問題のエラーは、デフォルトのタイプのすべての可能な選択肢を除外する制約が原因です。 –

関連する問題