user139014
user139014

Reputation: 1495

understanding the type signature of (.)

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

Answers (2)

daniel gratzer
daniel gratzer

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

wit
wit

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

Related Questions