2017-05-11 8 views
3

ハスケルの "filter"を使用しようとしていますが、固まってしまいました。 私はこのモジュロでのHaskellフィルタ操作

multipleOf7 :: [Int] -> [Int] 
multipleOf7 x = filter (test) x 
    where test = x mod 7 == 0 

のように1つの関数に一緒にフィルタと剰余を使用したい私はまたmodを使用しようとしましたが、それは動作しません。

答えて

2

あなたが理解しなければならないのは、Haskellが "非常に"統一された構文を持っていることです(それほど特別なケースではありません)。引数x yf x yの関数fを呼び出します。今すぐmodは他のすべての機能と同様に普通の機能です。だから、あなたがそれを呼び出す必要があります。

mod x 7 

また、同様の間で機能付きバイナリオペレータに電話をbackticsを使用することができます。

multipleOf7 :: [Int] -> [Int] 
multipleOf7 x = filter (test) x 
    where test x = mod x 7 == 0

x `mod` 7 

だからあなたが問題を解決することができます

以上のクリーナー:

multipleOf7 :: [Int] -> [Int] 
multipleOf7 = filter test 
    where test x = mod x 7 == 0
test = (0 ==) . flip mod 7 

など短いフィルタ行います:

それは mod x 7を見て最初は確かに奇妙である私の個人的な意見で
multipleOf7 :: Integral b => [b] -> [b] 
multipleOf7 = filter ((0 ==) . flip mod 7) 

(意見)をまた、そのようなことをtest機能を書き換えることができます。しかし、しばらくすると、複雑な構文/文法のルールを考慮しないで、多くの脳のサイクルを節約できるので、これを見つけることができます。あなたはバッククォート

x `mod` 7 == 0 

を使用してMOD書面または通常

mod x 7 == 0 

Haskellではあなたは中置として任意の関数を使用することができ、それを使用している必要があり

+0

ありがとう、私の小さな問題は解決しました! –

3

。 あなたはそれが好きで使用することができたい場合は、その後

myFunction x y = x * y 

のような簡単な関数を定義する場合:あなたはまた、中置スタイルと機能を定義することができますしたい場合

z = 40 `myFunction` 50 

厳密に同じになる、とあなたはまだ、他の方法でそれを呼び出すことができるだろう
x `myFunction` y = x * y 

z = myFunction 40 50 


また、同じ精神では、あなたが簡単にできますHaskellでカスタム中置演算子/記号を定義する。例えば:この方法を使用することができます

(-!!->) a b = (a,b) 
-- or identically, but no need for backticks for infix operators 
a -!!-> b = (a,b) 

c = 1 -!!-> 2 
-- and now c == (1,2) 

をしかし、これは慎重に使用する必要があり、かつ可読性のIMHOの明確な意図を持つ、慎重にあなたのカスタムシンボルを選択してください。

+0

ああ、ありがとう! 問題はちょっとしたことだとわかっていましたが、見つけられませんでした! –

1

ウィレム・ヴァンOnsem同様

multipleOf7 :: [Int] -> [Int] 
multipleOf7 ns = filter f ns 
    where 
    f :: Int -> Bool 
    f i = i `mod` 7 == 0 

=のInt、

filter :: (a -> Bool) -> [a] -> [a]のであなたのケースでは、私はloosen the Int into an Integral a => aおそらくだろう、ライブラリ関数mod :: Integral a => a -> a -> aがちょうど一般的なようであるから。私はまた、Nにをパラメータditch the nsとラムダとしてFを記述します

multipleOf :: Integral a => a -> [a] -> [a] 
multipleOf n = filter (\i -> i `mod` n == 0) 

ウィレムヴァンOnsem次いでpointfree styleにそれを書き換える:

multipleOf7 :: Integral a => [a] -> [a] 
multipleOf7 = filter ((0 ==) . flip mod 7) 

Pointfreeスタイル時には読みやすくなります。私はこれがここに当てはまらないと主張したい。別のバリエーションがここにあります、

multipleOf :: Integral a => a -> [a] -> [a] 
multipleOf n = filter ((== 0) . (`mod` n)) 

はそれでも、私はwhereまたはラムダより良いとの最初のバージョンが好きです。

関連する問題