Generalized list-comprehension

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. It's important that the elements are precisely in this order. I tried rewriting the listcomprehension to map, concat and filter, but that only complicated things. There is a possibility where I can write a function that gives the next of a list. So the next of [1,1,1] would be [1,1,2], but that would be somewhat inefficient when the list becomes large. Then I just call this function with (replicate n (head $ fu n)) and (last $ fu n). Then I just apply this function next to the rest, until I reach a state where all elements of the list equal the last value of the inputlist, so I have the required list of length n. Then to simply get the complete list as in function f. I need to map(\x->otherFunction x) [1..], but this "next"-function is almost identical to what the built-in listcomprehension does. I just don't like my solution. Then I can probably use Template Haskell(which I have never used), but that seems overkill. So does anyone has a better solution? Greets Ron __________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free web site building tool. Try it! http://webhosting.yahoo.com/ps/sb/

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

There was an exchange about "powerset" here some time ago, before and after this message: http://www.haskell.org/pipermail/haskell-cafe/2003-June/004507.html I think some of the ideas suggested there might be adaptable to this problem: look for sample code with sub-functions for generating combinations of a given length. Alternatively, here's something to conjure with: concat [sequence $ replicate n [1,2,3,4] | n <- [1..4]] (noting that the [1,2,3,4] and [1..4] can be parameterized.) #g -- At 07:35 31/01/04 -0800, Ron de Bruijn wrote:
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. It's important that the elements are precisely in this order.
I tried rewriting the listcomprehension to map, concat and filter, but that only complicated things.
There is a possibility where I can write a function that gives the next of a list. So the next of [1,1,1] would be [1,1,2], but that would be somewhat inefficient when the list becomes large. Then I just call this function with (replicate n (head $ fu n)) and (last $ fu n). Then I just apply this function next to the rest, until I reach a state where all elements of the list equal the last value of the inputlist, so I have the required list of length n. Then to simply get the complete list as in function f. I need to map(\x->otherFunction x) [1..], but this "next"-function is almost identical to what the built-in listcomprehension does. I just don't like my solution.
Then I can probably use Template Haskell(which I have never used), but that seems overkill.
So does anyone has a better solution?
Greets Ron
__________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free web site building tool. Try it! http://webhosting.yahoo.com/ps/sb/ _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
------------ Graham Klyne For email: http://www.ninebynine.org/#Contact

is this what you want? not sure if i've understood, and not sure it's efficient. andrew grow :: Int -> [[Int]] -> [[Int]] grow n (x:xs) = x:(grow n (xs ++ [x++[i] | i <- [1..n]])) seqn :: Int -> [[Int]] seqn n = grow n [[i] | i <- [1..n]] main :: IO () main = do print $ take 100 (seqn 3) Ron de Bruijn said:
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. It's important that the elements are precisely in this order.
I tried rewriting the listcomprehension to map, concat and filter, but that only complicated things.
There is a possibility where I can write a function that gives the next of a list. So the next of [1,1,1] would be [1,1,2], but that would be somewhat inefficient when the list becomes large. Then I just call this function with (replicate n (head $ fu n)) and (last $ fu n). Then I just apply this function next to the rest, until I reach a state where all elements of the list equal the last value of the inputlist, so I have the required list of length n. Then to simply get the complete list as in function f. I need to map(\x->otherFunction x) [1..], but this "next"-function is almost identical to what the built-in listcomprehension does. I just don't like my solution.
Then I can probably use Template Haskell(which I have never used), but that seems overkill.
So does anyone has a better solution?
Greets Ron
__________________________________ Do you Yahoo!? Yahoo! SiteBuilder - Free web site building tool. Try it! http://webhosting.yahoo.com/ps/sb/ _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- personal web site: http://www.acooke.org/andrew personal mail list: http://www.acooke.org/andrew/compute.html

Hi,
Another solution:
f m n = concat $ take m $ tail xs
where
xs = [[]]:map (\x -> concatMap (\y -> map (y:) x) [1..n]) xs
f 3 4 gives your f 4.
Hope it helps,
Koji Nakahara
On Sat, 31 Jan 2004 07:35:38 -0800 (PST)
Ron de Bruijn
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>
<snip>

I need to map(\x->otherFunction x) [1..], but this "next"-function is almost identical to what the built-in listcomprehension does. I just don't like my solution.
Sorry, I didn't read this.
You may prefer something like this to map (\x -> otherFunction x),
though mechanical translation:
xs = [[]]:[[ y:z | y <- [1..n], z <- x] | x <- xs]
Hope it helps,
Koji Nakahara
On Sun, 1 Feb 2004 15:22:01 +0900
Koji Nakahara
Hi,
Another solution:
f m n = concat $ take m $ tail xs where xs = [[]]:map (\x -> concatMap (\y -> map (y:) x) [1..n]) xs
f 3 4 gives your f 4.
participants (5)
-
andrew cooke
-
Bruno Cesar dos Santos Oliveira
-
Graham Klyne
-
Koji Nakahara
-
Ron de Bruijn