2016-05-01 15 views
0

私は整数の「小さな」除数を計算する必要がある問題を解決しようとしています。私はちょうど私が書きたい10の約数を取得するには、与えられた数の平方根までのすべての数字を通じてbruteforcingよ:なぜこのスニペットは明示的な値で有効ですが、関数として無効ですか?

[k|k<-[1...floor(sqrt 10)],rem 10 k<1] 

これはうまく動作しているようです。しかし、すぐに私は機能

f n=[k|k<-[1...floor(sqrt n)],rem n k<1] 

そして実際にコールこの機能では、このプラグとして、私は私の知る限りは、その印刷物実際印刷機能をundrestandとしてエラー

f 10 

No instance for (Floating t0) arising from a use of `it' 
The type variable `t0' is ambiguous 
Note: there are several potential instances: 
    instance Floating Double -- Defined in `GHC.Float' 
    instance Floating Float -- Defined in `GHC.Float' 
In the first argument of `print', namely `it' 
In a stmt of an interactive GHCi command: print it 

を得ますかコンソールへの結果は問題を引き起こしていますが、何が間違っているかを知ることはできません。 typeはあいまいですが、関数は明らかに整数のリストしか返せません。その後、再び私はタイプをチェックし、それがfの(推論)タイプは、私はfは、任意の実際の数値を受け入れることができなければならないことを理解することができますが、誰もが説明できる

f :: (Floating t, Integral t, RealFrac t) => t -> [t] 

である理由リターンタイプがすべきIntegralまたはint以外のものはありますか?

答えて

3
[k|k<-[1...floor(sqrt 10)],rem 10 k<1] 

最初10は後者のものと同じではありませんので、これは動作します - これを見て、私たちはあなたの関数の型シグネチャを必要とする:

sqrt :: Floating a => a -> a 
rem :: Integral a => a -> a -> a 

ので、最初のものは、それが動作することを意味し浮動小数点表現を持っているもののため - 別名FloatDouble ...、2つ目の作品IntInteger(BIGINT)、Word8(符号なし8ビット整数)のための...

だから、10sqrt 10の場合、コンパイラは - 浮動小数点数、ヌル問題、そして10rem 10 kで、これは数値のような整数でもあります。

しかし、あなたが機能でそれらを束ねるとき - あなたはnは、整数、浮動小数点なければならないと言っている、コンパイラはそのような事を知っていないと - 文句を言います。

これを修正するにはどうすればよいですか?また、haskellのサイドノートの範囲は..ではなく、...!と表示されます。ですから、具体的な解決策を取り、それを一般化することから始めましょう。

f :: Int -> [Int] 
f n = [k|k <- [1..n'],rem n k < 1] 
    where n' = floor $ sqrt $ fromIntegral n 

neccessary部分は浮動小数点数にIntに変換しました。しかし、あなたがすべてのユーザーがIntを使用してスティックする必要があるライブラリーに入れているのであれば、大丈夫ですが、理想からは遠いです - どうすれば(約束どおりに)一般化できますか?私たち自身が怠惰な傾向にある怠惰な言葉を使って、私たちはGHCiを使ってこれを行います。

我々は、我々はこれを取ると、ライブラリに、誰かが同様に動作することをWord8またはIntegerで働いていた場合にそれを置くことができます

-- f :: Int -> [Int] 
f n = [k|k <- [1..n'],rem n k < 1] 
    where n' = floor $ sqrt $ fromIntegral n 


$> ghci MyLib.hs 
.... 
MyLib > :type f 
f :: Integral a => a -> [a] 

型シグネチャをコメントアウトすることから始めます。

別の解決策は、rem (floor n) k < 1を使用し、タイプとして

f :: Floating a, Integral b => a -> [b] 

を持っているだろうが、それは一種の厄介になります。

+0

詳細な説明はありがとうございます。ある時点で、あなたはすべての私のhaskellの質問に答えるように思われるので、ヒントの瓶をセットアップする必要があります=) – flawr

関連する問題