How a Haskell filter works with a module
You must write a written mod using backquote
x `mod` 7 == 0
or use it normally
mod x 7 == 0
In haskell, you can use any function like infix. If you define a simple function like
myFunction x y = x * y
then if you want you can use it like:
z = 40 `myFunction` 50
if you like, you can also define a function with infix type.
x `myFunction` y = x * y
it will be strictly the same, and you can still call it in a different way:
z = myFunction 40 50
Also, along the same lines, you can easily define custom infix operators / symbols in Haskell. For example:
(-!!->) a b = (a,b)
-- or identically, but no need for backticks for infix operators
a -!!-> b = (a,b)
which can be used like this:
c = 1 -!!-> 2 -- and now c == (1,2)
but this should be used sparingly, choose your custom character carefully and with a clear intention of readability IMHO.
source to share
What you should understand is that Haskell has a "very" uniform syntax (there aren't many "special" cases). You call a function f
with arguments x y
using f x y
. Now mod
it's just a regular function like all other functions. Therefore, you should call him:
mod x 7
You can also use callbacks to call a binary operator with a function in between such as:
x `mod` 7
So, you can fix the problem with
multipleOf7 :: [Int] -> [Int]
multipleOf7 x = filter (test) x
where test x = mod x 7 == 0
or cleaner:
multipleOf7 :: [Int] -> [Int]
multipleOf7 = filter test
where test x = mod x 7 == 0
You can also rewrite the function test
so that:
test = (0 ==) . flip mod 7
or make a shorter filter like:
multipleOf7 :: Integral b => [b] -> [b] multipleOf7 = filter ((0 ==) . flip mod 7)
(opinion) In my personal opinion, it is really strange to see at first mod x 7
. But after a while, you will start to find it useful, as it saves a lot of brain cycles by not taking into account complex syntax / grammar rules.
source to share
Since filter :: (a -> Bool) -> [a] -> [a]
in your case a = Int,
multipleOf7 :: [Int] -> [Int]
multipleOf7 ns = filter f ns
where
f :: Int -> Bool
f i = i `mod` 7 == 0
Similar to Willem Van Onsem, I will probably decouple Int in the integral a => a , since it is a library function mod :: Integral a => a -> a -> a
as it is in general. I would also parameterize 7 to n, cut ns, and write f as a lambda:
multipleOf :: Integral a => a -> [a] -> [a]
multipleOf n = filter (\i -> i `mod` n == 0)
Then Willem Van Onsem rewrites it into a dotless style :
multipleOf7 :: Integral a => [a] -> [a] multipleOf7 = filter ((0 ==) . flip mod 7)
Pointfree style is sometimes more readable. I would say that it is not. Another option is also available here,
multipleOf :: Integral a => a -> [a] -> [a]
multipleOf n = filter ((== 0) . (`mod` n))
However, I like the first versions with where
or lambda better.
source to share