user2999349
user2999349

Reputation: 879

Haskell : why f1 . f2 xy not working?

I'm a bit confused concerning the dot operator. I've got the following code (for testing):

test :: Int -> Int -> Int
test x y = f1 . f2 x y 
           where f1 n = n+1
                 f2 x' y' = x' * y'

And I figured it would first execute (f2 x y) and then f1 on that result, but instead it throws an error. Could anyone tell me the exact definition of the dot operator and what equals f1 . f2 x y? (when written without the dot operator)

Best regards, Skyfe.

EDIT: If the dot operator yields a complete new function I figured the following code should work:

test :: Int -> Int -> Int
test x y = f1 . f2 x
           where f1 n = n+1
                 f2 x' y' = x' + y'

But also that code returns an error.

Upvotes: 1

Views: 534

Answers (3)

Franky
Franky

Reputation: 2376

(I think the other answers come up with $ too quickly)

As you already know,

f1 . f2 x

is parsed as

f1 . (f2 x)

Write

(f1 . f2) x

instead to do what it reads: compose f2 and f1 and then apply this composed function to x. Now

($) :: (a -> b) -> a -> b
f $ x = f x

looks like it is superfluous. Its primary purpose is that it has the lowest precedence, so you can avoid parentheses:

foo . bar . baz $ x + y * z = (foo . bar . baz) (x + y * z)

See also: Haskell: difference between . (dot) and $ (dollar sign)

Upvotes: 2

dfeuer
dfeuer

Reputation: 48611

One common approach is to combine (.) with ($):

f1 . f2 $ x

This can be extended easily to build up longer "pipelines":

f1 . f2 . f3 . f4 $ x

and then, if you find yourself needing that same combo elsewhere, you need only cut and paste:

fs = f1 . f2 . f3 . f4

... fs x ... fs y

Upvotes: 2

jamshidh
jamshidh

Reputation: 12070

Infix operators always have lower precedence than function application in Haskell, so this

f1 . f2 x

parses like this

f1 . (f2 x)

but, f2 x is not of type function (well, it could be if f2 returns a function, but that is not so in general, or in your problem). Since (.) acts on functions, this won't work.

Use ($) instead

f1 $ f2 x

Upvotes: 7

Related Questions