使用箭头实现快速排序有什么问题?

问题描述 投票:0回答:2

好吧,所以我想到用箭头来找点乐子。我尝试将性感的 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

有人能发现问题吗?

haskell arrow-abstraction
2个回答
6
投票

问题是你并没有真正分开

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


6
投票

第一个过滤器的谓词不正确。

(qs.) . filter . (<)

应该是

(qs.) . filter . (>)
© www.soinside.com 2019 - 2024. All rights reserved.