Reputation: 2098
what is the difference between
dotEx1 = map(+3) . filter (>100)
and
dotEx1 xs = map(+3) . filter (>100) xs
since
myFilter xs = filter (>100) xs
and
myFilter = filter (>100)
are the same why isn't
dotEx1 = map(+3) . filter (>100)
and
dotEx1 xs = map(+3) . filter (>100) xs
the same?
Upvotes: 1
Views: 98
Reputation: 684
The dot operator has low precedence because you want to partially apply functions. That is,
map (+3) . filter (>100)
is read as
(map (+3)) . (filter (>100))
By extension you get
dotEx1 xs = (map (+3)) . (filter (>100) xs)
instead of
dotEx1 xs = (map (+3) . filter (>100)) xs
A more readable version that also works:
dotEx1 xs = map (+3) . filter (>100) $ xs
Upvotes: 3
Reputation: 477641
The dot operator has signature:
(.) :: (b -> c) -> (a -> b) -> a -> c
here the operator is used infix. So in your first statement you have actually written:
dotEx1 = (.) (map (+3)) (filter (>100))
And that makes sense since filter (>100)
has signature: (Num n,Ord n) => [n] -> [n]
and map (+3)
has signature Num n => [n] -> [n]
. If you however write:
dotEx1 xs = (.) (map (+3)) (filter (>100) xs)
then filter (>100) xs
has signature (Num n,Ord n) => [n]
and so this is a value (not a function, or perhaps a function with no arguments). So the dot operator cannot be used (the types do not match).
Informally the dot operator should be given two functions f
and g
and it generates a function where f
is applied after g
is applied on the input. But g
thus has to be a function taking one argument.
Upvotes: 4
Reputation: 36385
The .
function is defined as this:
(.) :: (b -> c) -> (a -> b) -> a -> c
The function composed by the .
operator must accept an argument. Therefore,
dotEx1 = map(+3) . filter (>100)
Is the same as
dotEx1 xs = (map(+3) . filter (>100)) xs
Upvotes: 7