Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expressing long chain of compositions in Haskell

(unimportant background info / motivation)

I was implementing a different version of nub, inspired by the Yesod book's discouragement of using it.

map head . group . sort is more efficient than a call to nub. However, in our case, order is important...

So I set out writing a "better" nub akin to the order-unimportant version. And I ended up with this:

mynub = unsort . map head . groupBy (\x y -> fst x == fst y) . sortBy (comparing fst) . rememberPosition

rememberPosition = flip zip [0..]
unsort = map fst . sortBy (comparing snd)

This certainly does a lot of extra work, but it should be O(n log n) instead of original nub's O(n2). But that's beside the point. The problem is, it's so long! It's really not that complicated, but it's long (and I'm one of those people that hates going wider than 80 columns, or horizontal scrollbars on StackOverflow code blocks).

(the question)

What are better ways in Haskell for expressing long chains of function composition such as this?

like image 351
Dan Burton Avatar asked Apr 20 '11 03:04

Dan Burton


2 Answers

Break up the line, and use the layout:

mynub = unsort 
      . map head 
      . groupBy ((==) `on` fst)
      . sortBy (comparing fst) 
      . rememberPosition
like image 129
Don Stewart Avatar answered Nov 20 '22 05:11

Don Stewart


line width is easily solved :)

> mynub = { unsort 
>         . map head 
>         . groupBy (\x y -> fst x == fst y) 
>         . sortBy (comparing fst) 
>         . rememberPosition
>         }

but I'm barely used to reading composition right to left. Top to bottom is a bit much. Arrow or (>>>)=flip (.) looks nicer to me, but I have no idea if it would be idiomatic

> mynub = { rememberPosition
>       >>> sortBy (comparing fst) 
>       >>> groupBy (\x y -> fst x == fst y) 
>       >>> map head 
>       >>> unsort 
>         }
like image 28
llayland Avatar answered Nov 20 '22 04:11

llayland