Thursday, January 3, 2008

Sharper function operators

I read The Point of Pointfree today and thought of how function composition and function application operators look like in F# and how they differ from Haskell's. Most notably there are operators for application and composition from both the left and the right.

val ( <| ) : ('a -> 'b) -> 'a -> 'b
val ( |> ) : 'a -> ('a -> 'b) -> 'b
val ( >> ) : ('a -> 'b) -> ('b -> 'c) -> ('a -> 'c)
val ( << ) : ('b -> 'c) -> ('a -> 'b) -> ('a -> 'c)


If we would do this in Haskell, it could look like this:

import Control.Arrow

infixr 0 <|
infixl 0 |>
infixr 9 <.<
infixl 9 >.>

-- >> in F#
(>.>) :: (a -> b) -> (b -> c) -> a -> c
(>.>) = (>>>)

-- <<>
(<.<) :: (b -> c) -> (a -> b) -> a -> c
(<.<) = (.)


-- |> in F#
(|>) :: a -> (a -> b) -> b
(|>) = flip ($)

-- <| in F#
(<|) :: (a -> b) -> a -> b
(<|) = ($)


Now

grep '^X-Spam-Level' | sort | unique | wc -l

length . nub . sort . filter (isPrefixOf "X-Spam-Level")

becomes

filter (isPrefixOf "X-Spam-Level") >.> sort >.> nub >.> length

Or even:

getContents >>= \x -> x
 |> lines
 |> filter (isPrefixOf "X-Spam-Level")
 |> sort
 |> nub
 |> length
 |> return


which I find rather neat. Now it looks even more like Unix shell pipelining.

EDIT: I'm starting to really not like the wysiwyg editor.