Reputation: 1495
I'm just learning Haskell and functional programming using Richard Bird's book and came across the type signature of the (.) function. Namely
(.) :: (b -> c) -> (a -> b) -> (a -> c)
and the associated definition
(f . g) x = f (g x)
I understand what the operator is doing but am a bit confused about how to read the type signature. Is it saying that (.) takes as its first argument a function of type (b -> c), then returns a function of type (a -> b), and finally returns a function of type (a -> c)? Is this the right way to read the type signature?
Also, could this be an example of currying, where (.) is a curried function that takes two parameters? Or is that not the correct way to think about currying?
Upvotes: 4
Views: 202
Reputation: 53881
You've almost got it, it takes a b -> c
and returns a function (a -> b) -> (a -> c)
which, when given an (a -> b)
returns a function a -> c
. It may also be helpful to know that in Haskell, you can wrap an operator in parens and use it prefix so
f . g === (.) f g
Now it's easier to see the currying
((.) f) g === f . g
Finally, notice that this type signature is equivalent to
(b -> c) -> (a -> b) -> a -> c
Since ->
is right associative.
Upvotes: 12
Reputation: 1622
You can read function signatures with several arguments like this:
(.) :: (b -> c) -> ((a -> b) -> (a -> c))
so, (f .) :: (a -> b) -> (a -> c)
Next is the same:
foo :: a -> b -> c -> d -> e
foo :: a ->(b ->(c ->(d -> e)))
Function (.)
takes 2 functions (a -> b)
as a parameters and return their composition
Upvotes: 4