[Haskell-cafe] Generalized list-comprehension

Bruno Cesar dos Santos Oliveira Bruno.Oliveira at comlab.ox.ac.uk
Sat Jan 31 16:51:21 EST 2004


Hello Ron!


> Hi there,
> 
> I have written this little function:
> 
> f :: (Num a, Enum a) => a -> [[a]]
> f n =  [[a]|a<-fu n] ++ [a:[b]|a<-fu n,b<-fu n] ++
> [a:b:[c]|a<-fu n,b<-fu n,c<-fu n]
> fu n = [1..n]
> 
> This is an example of the function in action:
> 
> *Mod> f 4
> [[1],[2],[3],[4],[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[2,4],[3,1],[3,2],[3,
> 3],[3,4],[4,1],[4,2],[4,3],[4,4],[1,1,1],[1,1,2],[1,1,3],[1,1,4],[1,2,1],[1,2,2]
> ,[1,2,3],[1,2,4],[1,3,1],[1,3,2],[1,3,3],[1,3,4],[1,4,1],[1,4,2],[1,4,3],[1,4,4]
> ,[2,1,1],[2,1,2],[2,1,3],[2,1,4],[2,2,1],[2,2,2],[2,2,3],[2,2,4],[2,3,1],[2,3,2]
> ,[2,3,3],[2,3,4],[2,4,1],[2,4,2],[2,4,3],[2,4,4],[3,1,1],[3,1,2],[3,1,3],[3,1,4]
> ,[3,2,1],[3,2,2],[3,2,3],[3,2,4],[3,3,1],[3,3,2],[3,3,3],[3,3,4],[3,4,1],[3,4,2]
> ,[3,4,3],[3,4,4],[4,1,1],[4,1,2],[4,1,3],[4,1,4],[4,2,1],[4,2,2],[4,2,3],[4,2,4]
> ,[4,3,1],[4,3,2],[4,3,3],[4,3,4],[4,4,1],[4,4,2],[4,4,3],[4,4,4]]
> *Mod>
> 
> This is ofcourse nice and all, but I need a function
> that does this same trick, but then doesn't only
> generate listelements
> of the maximum hard-coded length of three, but to
> length m, where m is an extra parameter.

See if this meets your needs:

cafe1 _ 0 = ([[]],[])
cafe1 n m = let
                (p,u) = cafe1 n (m-1)
                new = [i:j | i <- [1..n], j <- p]
            in (new,u ++ new)

cafe2 n = snd . cafe1 n

Usage (for your example):

Test> cafe2 4 3
[[1],[2],[3],[4],[1,1],[1,2],[1,3],[1,4],[2,1],[2,2],[2,3],[2,4],[3,1],[3,2],[3,3],[3,4],
[4,1],[4,2],[4,3],[4,4],[1,1,1],[1,1,2],[1,1,3],[1,1,4],[1,2,1],[1,2,2],[1,2,3],[1,2,4],
[1,3,1],[1,3,2],[1,3,3],[1,3,4],[1,4,1],[1,4,2],[1,4,3],[1,4,4],[2,1,1],[2,1,2],[2,1,3],
[2,1,4],[2,2,1],[2,2,2],[2,2,3],[2,2,4],[2,3,1],[2,3,2],[2,3,3],[2,3,4],[2,4,1],[2,4,2],
[2,4,3],[2,4,4],[3,1,1],[3,1,2],[3,1,3],[3,1,4],[3,2,1],[3,2,2],[3,2,3],[3,2,4],[3,3,1],
[3,3,2],[3,3,3],[3,3,4],[3,4,1],[3,4,2],[3,4,3],[3,4,4],[4,1,1],[4,1,2],[4,1,3],[4,1,4],
[4,2,1],[4,2,2],[4,2,3],[4,2,4],[4,3,1],[4,3,2],[4,3,3],[4,3,4],[4,4,1],[4,4,2],[4,4,3],
[4,4,4]] :: [[Integer]]

I haven't lost much time making the function very well written. It
should be possible to define it as an unfold.

Best Regards,

Bruno



More information about the Haskell-Cafe mailing list