Dan Burton
Dan Burton

Reputation: 53665

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?

Upvotes: 12

Views: 1683

Answers (2)

Don Stewart
Don Stewart

Reputation: 137947

Break up the line, and use the layout:

mynub = unsort 
      . map head 
      . groupBy ((==) `on` fst)
      . sortBy (comparing fst) 
      . rememberPosition

Upvotes: 17

llayland
llayland

Reputation: 203

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 
>         }

Upvotes: 8

Related Questions