关于编码风格:在Haskell中表达长链组合

Expressing long chain of compositions in Haskell

(不重要的背景信息/动机)

我当时正在实施一个不同版本的nub,这是受Yesod图书不鼓励使用它的启发。

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

所以我开始写一个"更好"的nub,类似于订单不重要的版本。最后我得到了:

1
2
3
4
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)

这当然会做很多额外的工作,但是应该是O(n log n)而不是原始的nub的O(n2)。但这不是重点。问题是,时间太长了!它并没有那么复杂,但很长(我是那种不喜欢扩展到80列或StackOverflow代码块上的水平滚动条的人之一)。

(问题)

在haskell中,有什么更好的方法可以表达这样长的功能组成链?


分解行,并使用布局:

1
2
3
4
5
mynub = unsort
      . map head
      . groupBy ((==) `on` fst)
      . sortBy (comparing fst)
      . rememberPosition

线条宽度很容易解决:)

1
2
3
4
5
6
> mynub = { unsort
>         . map head
>         . groupBy (\x y -> fst x == fst y)
>         . sortBy (comparing fst)
>         . rememberPosition
>         }

但我几乎不习惯从右向左看作文。从上到下是有点多。arrow或(>>>)=flip(.)对我来说更合适,但我不知道它是否是惯用的

1
2
3
4
5
6
> mynub = { rememberPosition
>       >>> sortBy (comparing fst)
>       >>> groupBy (\x y -> fst x == fst y)
>       >>> map head
>       >>> unsort
>         }