1

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?

2
  • Because of the dot operator? Commented Feb 15, 2017 at 11:51
  • 1
    I feel like the extant answers don't actually address your question straight on: they say "how to fix it" but not "why it's wrong". The one-sentence answer to that part is pretty simple: function application has higher precedence than any infix operator, including (.). (I don't really think this one sentence adds enough value to warrant putting in yet another answer, though.) Commented Feb 15, 2017 at 18:21

3 Answers 3

7

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
Sign up to request clarification or add additional context in comments.

Comments

4

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.

Comments

3

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.