Hi Oscar,

Define

    result = (.)

Then '(result f) g' applies f to the result part of a function g.  That's what you want when negating the result of not.  For (==), you want to negate the result of the result, so you'd instead say '(result.result) not (==)'.  Keep composing result for deeper applications.

If you want to edit/transform the first or second part of a pair instead of the result of a function, then you'd use 'first' or 'second' in place of 'result'.

If you think of f (here f=not) as an "semantic editor" (transformer) of values, then 'result', 'first', and 'second' are "semantic editor combinators", which can be composed together arbitrarily.  See http://conal.net/blog/semantic-editor-combinators .

   - Conal

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 . (==)

<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