to answer my own question:

On Nov 7, 2010, at 8:33 PM, Sebastian Fischer wrote:

Can you, for example, define a `perm` arrow that yields every permutation of it's input? Monadic implementations look like they need `>>=` but there may be another way..

A `perm` arrow can be defined in the "usual" way using the list-arrow package:

    {-# LANGUAGE TypeOperators #-}

    import Control.Arrow
    import Control.Arrow.ArrowList

    perm :: (ArrowList (~>), ArrowPlus (~>)) => [a] ~> [a]
    perm = isA null <+> (uncons >>> second perm >>> insert)

    insert :: (ArrowList (~>), ArrowPlus (~>)) => (a,[a]) ~> [a]
insert = cons <+> (second uncons >>> rearrange >>> second insert >>> cons)
     where rearrange = assocL >>> first swap >>> assocR

It may be possible to do this with `ArrowChoice` only, that is, without resorting to the operations of `ArrowList`, but they looked simpler.

In order to support the above, we need a bunch of auxiliary arrows. First, list con- and destructors:

    cons :: Arrow (~>) => (a,[a]) ~> [a]
    cons = arr (uncurry (:))

    uncons :: ArrowList (~>) => [a] ~> (a,[a])
    uncons = isA (not . null) >>> arr (\ (x:xs) -> (x,xs))

Second (and more annoyingly), "reordering" arrows:

    swap :: Arrow (~>) => (a,b) ~> (b,a)
    swap = arr (\ (x,y) -> (y,x))

    assocL :: Arrow (~>) => (a,(b,c)) ~> ((a,b),c)
    assocL = arr (\ (x,(y,z)) -> ((x,y),z))

    assocR :: Arrow (~>) => ((a,b),c) ~> (a,(b,c))
    assocR = arr (\ ((x,y),z) -> (x,(y,z)))

This is my first program with arrows so it might be unnecessarily complicated. Is there a more elegant way?

I wonder how badly my use of `arr` influences how the program can be optimized. I hope it's still better than just using

    perm = arrL perms
     where perms :: [a] -> [[a]]
           perms = ...

;o)

Sebastian
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to