Reputation: 879
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
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
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
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