2008/12/26 Oscar Picasso <oscarpicasso@gmail.com>
Hi,

I can write:
*Main> let yes = not . not
*Main> :t yes
yes :: Bool -> Bool

But not:
*Main> let isNotEqual = not . (==)

The definition of (.):

f . g = \x -> f (g x)

So:

not . (==) = \x -> not ((==) x)

But (==) x is a function (of type a -> Bool, which returns whether its argument is equal to x), not a Bool as not is expecting.

Composition like that usually only works for single argument functions.  It gets uglier quickly for multi arg functions:

isNotEqual =  (not .) . (==)

You can define your own operator to help:

(.:) = (.) . (.)

Which is a bit of silly definition.  I typically don't like pointfree style for any but the most transparent of uses, so in real life (tm), I'd probably write:

(f .: g) x y = f (g x y)

But be prepared for others to disagree with me.

Luke



<interactive>:1:23:
    Couldn't match expected type `Bool'
           against inferred type `a -> Bool'
    Probable cause: `==' is applied to too few arguments
    In the second argument of `(.)', namely `(==)'
    In the expression: not . (==)

Why?

Oscar


_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe