I'm trying to take out every number between 1 to 10 that is divisible by either 5 or 3
Here is my code till now -
giveList =
[ x
| x <- [1..10] ,
(x `mod` 5 == 0) or (x `mod` 3 == 0)
]
And then I load the function in ghci. But it's giving me a error -
> [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.
My question is -
- Can we use 'or' in list comprehensions?
- If not, please tell me how it can be done in other ways
I'm new to functional programming, please help me.
You can use or
in list comprehensions, but
Prelude> :t or
or :: [Bool] -> Bool
that is not the one you need at that place, it's a function that checks whether any element in the list is True
. There you need
(||) :: Bool -> Bool -> Bool
And if you want to use a function with a name consisting of letters infix, you need to enclose it in backticks, like you did with mod
, but since or
takes only one argument, you cannot apply that function infix.
A correct version of your list would be
giveList = [ x | x <- [1 .. 10], x `mod` 5 == 0 || x `mod` 3 == 0]
or
has a type signature of or :: [Bool] -> Bool
. It takes a list of Boolean values, and returns True
if any one of them is True
, or False
otherwise.
The function you're looking for is || :: Bool -> Bool -> Bool
. It takes two Boolean values, and returns True
if either of them is True
, or False
otherwise.
[x | x <- [1..10], x `mod` 5 == 0 || x `mod` 3 == 0]
You can do list comprehension like that:
[x | x <- [1..10], ((x `mod` 3) == 0) || ((x `mod` 5) == 0)]
or
function works on lists
In fact, I might be not so bad to use or
here:
[x | x <- [1..10], or $ map ((==0).(x `mod`)) [3,5]]
... or probably more readable ...
[x | x <- [1..10], any (==0) $ map (x `mod`) [3,5]]
The down side is that it might look a little bit scary, but on the up side you can easily test for more divisors that way.