[Haskell-cafe] Re: help with Haskell programming

Sean Leather leather at cs.uu.nl
Sun Apr 18 13:25:11 EDT 2010


> This is the annoying part about Haskell . I can not understand composition
> .
>

One of the ways of understanding composition (and many other functions in
Haskell) is by trying to understand its type. Here it is shown by looking at
the type in the interpreter GHCi.

*Main> :t (.)
(.) :: (b -> c) -> (a -> b) -> a -> c

It's a function that takes three arguments, the first two of which are
functions, and the third is something else. Since (.) is a polymorphic
function, we can tell everything about it (if we ignore certain other
features of Haskell which are not immediately relevant). To give names to
things, let's say composition is declared as follows:

(.) f g x = ...

We know that the type of x must be the same as the type of the argument to
the function f. The result type of f is the same and the input type of g.
The result type of g is the result type of (.). From these observations, we
know that (.) applies g to x and f to the result of that. We can even write
that definition down.

(.) f g x = f (g x)

But, in the case of (.), we don't need to look at the definition to
understand how it works. We can get all the information from the type.

The next step in understanding (.) is seeing how it's used. If you want to
compose two functions, you can use their types to figure out what the result
is. You mentioned (.) (||), so let's look at that first. Then, we can use
GHCi to verify our understanding.

The type of (||) is Bool -> Bool -> Bool or, equivalently, Bool -> (Bool ->
Bool) (since -> is right associative). If we apply (.) to (||), then we can
substitute parts of the type of (||) into the type of (.) to figure out the
type of (.) (||) (which is equivalent to ((||) .).

First, note the types of the two components:

(.) :: (b -> c) -> (a -> b) -> a -> c
(||) :: Bool -> (Bool -> Bool)

Then, since (||) is plugged into the first argument of (.), we bind the
right-hand sides below (from the type of (||)) to the left-hand sides (from
(.)):

b = Bool
c = Bool -> Bool

The resulting type is:

(.) (||) :: (a -> Bool) -> a -> Bool -> Bool

and GHCi agrees. If you are looking for something of this type, then you've
found it. Otherwise, you need to rethink your definition.

Regards,
Sean
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20100418/15bd8409/attachment.html


More information about the Haskell-Cafe mailing list