문제

Ok, so I thought of having some fun with arrows. I tried to directly translate the sexy Haskell quicksort to an implementation that uses arrows instead. But it does not work correctly.

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

Can someone spot the problem?

도움이 되었습니까?

해결책

The problem is that you don't really split up the tail, the two comparisons aren't complemental. It becomes obvious when we write the first one as a lambda, too:

first ( (\x -> qs. . filter (x<))
    &&& (\x -> (x:) . qs . filter (>=x)) )

when what you want is obviously

first ( (\x -> qs. . filter (<x))
    &&& (\x -> (x:) . qs . filter (>=x)) )

or

first ( (qs.) . filter . (>)
    &&& (\x -> (x:) . qs . filter (x<=)) )

BTW, I'd prefer app over uncurry id.

다른 팁

The predicate of the first filter is incorrect.

(qs.) . filter . (<)

should be

(qs.) . filter . (>)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top