4

5または3で割り切れる1から10までのすべての数字を取り出そうとして
います。これまでのコードは次のとおりです-

giveList = 
[ x
 | x <- [1..10] ,
 (x `mod` 5 == 0) or (x `mod` 3 == 0)
]

そして、関数を ghci にロードします。しかし、それは私にエラーを与えています-

> [1 of 1] Compiling Main             ( problem1.hs, interpreted )

problem1.hs:4:10:
    The function `x `mod` 5 == 0' is applied to two arguments,
    but its type `Bool' has none
    In the expression: (x `mod` 5 == 0) or (x `mod` 3 == 0)
    In a stmt of a list comprehension:
      (x `mod` 5 == 0) or (x `mod` 3 == 0)
    In the expression:
      [x | x <- [1 .. 10], (x `mod` 5 == 0) or (x `mod` 3 == 0)]
Failed, modules loaded: none.

私の質問は -

  • リスト内包表記で「または」を使用できますか?
  • そうでない場合は、他の方法でそれを行う方法を教えてください

私は関数型プログラミングが初めてなので、助けてください。

4

4 に答える 4

13

orリスト内包表記で使用できますが、

Prelude> :t or
or :: [Bool] -> Bool

それはその場所で必要なものではありません。リスト内の要素が であるかどうかをチェックする関数ですTrue。そこにあなたが必要です

(||) :: Bool -> Bool -> Bool

また、中置文字で構成される名前の関数を使用する場合は、 の場合のようにバッククォートで囲む必要がありますが、mod引数orが 1 つしかないため、その中置記号を適用することはできません。

あなたのリストの正しいバージョンは

giveList = [ x | x <- [1 .. 10], x `mod` 5 == 0 || x `mod` 3 == 0]
于 2013-04-08T13:30:18.047 に答える
8

orの型シグネチャがありor :: [Bool] -> Boolます。ブール値のリストを取り、TrueそれらのいずれかがTrue、またはFalseそうでない場合に返します。

お探しの機能は|| :: Bool -> Bool -> Bool. 2 つのブール値を取りTrue、どちらかが であるか、Trueそうでないかを返しますFalse

[x | x <- [1..10], x `mod` 5 == 0 || x `mod` 3 == 0]
于 2013-04-08T13:30:49.810 に答える
2

次のようにリスト内包表記を行うことができます。

[x | x <- [1..10], ((x `mod` 3) == 0) || ((x `mod` 5) == 0)]

or関数はリストで機能します

于 2013-04-08T13:30:43.493 に答える
0

実際、ここで使用するのはそれほど悪くないかもしれませんor:

[x | x <- [1..10], or $ map ((==0).(x `mod`)) [3,5]]

...またはおそらくもっと読みやすい...

[x | x <- [1..10], any (==0) $ map (x `mod`) [3,5]]

マイナス面は、少し恐ろしく見えるかもしれないということですが、プラス面として、より多くの除数を簡単にテストできます。

于 2013-04-09T06:45:42.413 に答える