4

以下は True を返します (2147483647 は素数であるため)。

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 が発生するのはなぜですか? floor が RealFrac を取り、Integrals を作成したと思いましたか? さらに、上記の例に不満はありませんでした。そのときと同じように、より多くの整数を入力しているだけです。

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

2 に答える 2

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)

の値をfloatとして使用し、とnに渡します。次に、その結​​果をintとして使用し、その結果をに渡します。コンパイラーは、これらすべてのインスタンスで型に名前を付けることはできません。sqrtfloormod

最初の例で機能する理由、言い換えれば

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

これは、2つの異なる数値リテラルを使用しているためです。1つはintにすることができ、もう1つはfloatにすることができます。両方に同じ値を使用している場合はfromIntegral、intをfloatに変換するために呼び出す必要があります。

[2..]型シグネチャを追加し、次のように変更すると、別のエラーメッセージが表示される場合があります[2..] :: [Integer]

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

nこれにより、の値を2つの異なるタイプとして使用していることがより明確になる場合があります。

于 2011-09-08T21:08:40.477 に答える
-1

以下のCA McCannが指摘したように、私の答えは正しくありません:-)

私が見る限り、それはFloating、の型シグネチャsqrt

sqrt :: Floating a => a -> a

でプリコンポーズsqrtするとfromIntegral :: (Integral a, Num b) => a -> b、目的の結果が得られます。

    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]
于 2011-09-08T21:05:03.550 に答える