Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's wrong with this implementation of quicksort using Arrows?

Tags:

haskell

arrows

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?

like image 862
haskelline Avatar asked Apr 06 '13 10:04

haskelline


2 Answers

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.

like image 78
leftaroundabout Avatar answered Sep 22 '22 12:09

leftaroundabout


The predicate of the first filter is incorrect.

(qs.) . filter . (<)

should be

(qs.) . filter . (>)
like image 38
snak Avatar answered Sep 18 '22 12:09

snak