在Haskell中表达长合成链

在Haskell中表达长合成链,haskell,coding-style,function-composition,Haskell,Coding Style,Function Composition,(不重要的背景信息/动机) 我当时正在实现一个不同版本的nub,灵感来自于它的使用方法 地图头。小组。sort比调用nub更有效。然而,在我们的情况下,秩序是重要的 所以我开始写一个“更好”的要点,类似于订单不重要的版本。我最终得到了这样的结果: mynub = unsort . map head . groupBy (\x y -> fst x == fst y) . sortBy (comparing fst) . rememberPosition rememberPosition

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

我当时正在实现一个不同版本的
nub
,灵感来自于它的使用方法

地图头。小组。sort
比调用
nub
更有效。然而,在我们的情况下,秩序是重要的

所以我开始写一个“更好”的要点,类似于订单不重要的版本。我最终得到了这样的结果:

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(nlogn),而不是原始的nub的O(n2)。但这不是重点。问题是,太长了!它其实并没有那么复杂,但很长(我是那些讨厌超过80列或StackOverflow代码块上的水平滚动条的人之一)

(问题)


在Haskell中,有什么更好的方法可以表达这样的长函数组合链?

线宽很容易解决:)

但我几乎不习惯从右到左阅读作文。自上而下有点过分。 Arrow或(>>>)=flip(.)在我看来更好看,但我不知道它是否是惯用的

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

拆分该行,并使用布局:

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

(>>>)
有点单一,但定义在
库中:需要注意的三个重要事项
nub
只是有一个
Eq a
约束,而您的版本有一个
Ord a
约束
nub
适用于无限列表,而您的版本不适用。另外,
nub
的最坏情况可能比您的代码更糟,但它的最佳情况比您的代码更好。最显著的差异是
Ord a
约束。如果你允许,你可以写一些更复杂的东西,在最坏的情况下是O(n logn),在最好的情况下几乎和
nub
一样好,并且可以在无限列表上工作。但它涉及非列表数据结构。
mynub = unsort 
      . map head 
      . groupBy ((==) `on` fst)
      . sortBy (comparing fst) 
      . rememberPosition