Mark Needham

Thoughts on Software Development

Haskell vs F#: Function composition

with 11 comments

I’m reading through John Hughes’ ‘Why functional programming matters‘ paper and one thing I’ve come across which is a bit counter intuitive to me is the Haskell function composition operator.

I’ve written previously about F#’s function composition operator which is defined as follows:

let inline (>>) f g x = g(f x)

To write a function which doubled all the values in a list and then returned the odd values we’d do this:

let doubleThenOdd = (fun x -> x*2) >> List.filter (fun x -> x % 2 <> 0)

Of course it’s not possible for there to be any values!

doubleThenOdd [1..5];;
val it : int list = []

Based on that understanding I would expect the Haskell function composition operator (‘.’) to work in the same way:

let doubleThenOdd = map (\ x -> x*2) . filter (\ x -> (mod x 2) /= 0)

But it doesn’t!

Prelude> doubleThenOdd [1..5]

In Haskell the functions are applied from right to left rather than left to right as I had expected.

The definition of ‘.’ is therefore:

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

So to get what I wanted we’d need to switch around ‘map’ and ‘filter’:

let doubleThenOdd = filter (\ x -> (mod x 2) /= 0) . map (\ x -> x*2)
Prelude> doubleThenOdd [1..5]

It’s not too difficult to follow once I worked out that it was different to what I was used to but I was very confused for a while!

Is there a reason why they implement this operator differently?

Be Sociable, Share!

Written by Mark Needham

December 9th, 2009 at 10:10 pm

Posted in F#

Tagged with ,

  • Pingback: Tweets that mention Haskell vs F#: Function composition at Mark Needham --

  • MauricioC

    Standard function composition on math works right-to-left, (f o g)(x) = f(g(x)). I don’t know the reason for this, but it seems plausible that the Haskell folks were inspired by the math notation.

  • Hi,

    In F#, there are two composition operators: <>. <.

    let foo x = x |> f |> g
    can be changed into:
    let foo = f >> g
    The order remains the same. In the OOP world, you can write:
    let foo x = x.f.g

    |> and >> keep the same logic as the pipe | in shells. I tend to prefer them, as they show the order the function will be called.

    << and Haskell . operator follow the mathematical notation.

  • You can import Control.Arrow and use (>>>).

  • Paulo Pinto

    I prefer the Haskell notation, because it follows the standard math notation and it feels more natural to me.

    When reading F# code I always have to think on the evaluation order.

    Still both notations seem to me like syntactic sugar to avoid using extra parenthesis.

  • To avoid this, in Ioke I added two different operators for functional composition. If f and g are activatable things:

    f -> g ; the same as g(f(x))
    f <- g ; the same as f(g(x))

  • I’m not positive on this, but here’s my guess.

    Starting without point-free functions, you could write something like this:

    *Foo> let doubleThenOdd1 ints = filter (\x -> (mod x 2) /= 0) (map (*2) ints)
    *Foo> doubleThenOdd1 [1..5]

    You could then remove the parenthesis around map by using ‘$’:

    *Foo> let doubleThenOdd2 ints = filter (\x -> (mod x 2) /= 0) $ map (*2) ints
    *Foo> doubleThenOdd2 [1..5]

    And then the infix composition function allows you to write a point-free function that is very similar in structure to the previous examples:

    *Foo> let doubleThenOdd = filter (\x -> (mod x 2) /= 0) . map (*2)
    *Foo> doubleThenOdd [1..5]

    Monadic code, on the other hand, applies the first function to the infix function >>= first, which makes sense aesthetically because monadic operations have effects:

    Prelude> getLine >>= putStrLn

    If you really wanted a similar operator to F#’s though, it’s simple to implement using flip:

    infixr 9 .>
    (.>) :: (a -> b) -> (b -> c) -> a -> c
    (.>) = flip (.)

    *Foo> let doubleThenOdd’ = map (*2) .> filter (\x -> (mod x 2) /= 0)
    *Foo> doubleThenOdd’ [1,2,3,4,5]

  • The Haskell operator (.), as defined in the Haskell 1.0 report from 1990, is based on the mathematical operator ‘∘’, commonly given by:

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

    and defined in Haskell as:

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

    “Reverse composition” is (>>>) in the base library.

  • Pingback: Rick Minerich's Development Wonderland : F# Discoveries This Week 12/14/2009()

  • Haskell makes sense to me, as it’s just precedence rules.

    doubleThenOdd [1..5]
    > filter (\ x -> (mod x 2) /= 0) . map (\ x -> x*2) [1,2,3,4,5]
    > filter (\ x -> (mod x 2) /= 0) [2,4,6,8,10]
    > [2, 6, 10]

    You could imagine writing doubleThenOdd as:

    let doubleThenOdd n = filter (\ x -> (mod x 2) /= 0) (map (\ x -> x*2) n)

    which should do the same and makes the argument more obvious.

  • Pingback: J: Tacit Programming at Mark Needham()