好吧,所以我想到用箭头来找点乐子。我尝试将性感的 Haskell 快速排序直接转换为使用箭头的实现。但它无法正常工作。
import Control.Arrow
qs :: Ord a => [a] -> [a]
qs = isEmpty >>> right (head &&& tail
>>> first ((qs.) . filter . (<)
&&& (\x -> (x:) . qs . filter (>=x)))
>>> first (uncurry (&&&))
>>> uncurry id
>>> uncurry (++))
>>> extract
where
isEmpty [] = Left []
isEmpty x = Right x
extract (Left x) = x
extract (Right x) = x
有人能发现问题吗?
问题是你并没有真正分开
tail
,这两个比较不是互补的。当我们将第一个也写为 lambda 时,这一点就变得很明显了:
first ( (\x -> qs. . filter (x<))
&&& (\x -> (x:) . qs . filter (>=x)) )
当你想要的显然是
first ( (\x -> qs. . filter (<x))
&&& (\x -> (x:) . qs . filter (>=x)) )
或
first ( (qs.) . filter . (>)
&&& (\x -> (x:) . qs . filter (x<=)) )
顺便说一句,我更喜欢
app
而不是 uncurry id
。
第一个过滤器的谓词不正确。
(qs.) . filter . (<)
应该是
(qs.) . filter . (>)