Hello, I need to write a Haskell function that has:
input: a list of numbers >0 representing maximum values
output: a list of any possible combination of integers from 0 to the max-values
Here is an example:
If I wrote "function [4,2,3]" it should return the following list:
[ [0,0,0], [0,0,1], [0,0,2], [0,0,3], [0,1,0], [0,1,1], [0,1,2], [0,1,3], [0,2,0], [0,2,1], [0,2,2], [0,2,3], [1,0,0], and so on... [4,2,0], [4,2,1], [4,2,2], [4,2,3] ]
I know how to do this with a defined-length (pseudo)list this way:
functionL :: (Int,Int,Int) -> [(Int, Int, Int)]
functionL (a,b,c) = [ (a',b',c') | a'<-[0..a], b'<-[0..b], c'<-[0..c] ]
and it works, but I need a undefined-length list as input. I tried to write something like this:
functionL' :: [Int] -> [[Int]]
functionL' [] = []
functionL' (h:t) = [ (h' : (functionL' t)) | h'<-[0..h]]
but it shows a type error. Is there another way to achieve this?
Any help will be appreciated.
4 replies to this topic
#1
Posted 16 February 2011 - 02:48 AM
|
|
|
#2
Posted 16 February 2011 - 09:18 AM
Uh oh, you're problem is how you're pattern matching against the elements in the list:
functionL' (h:t) = [ (h' : (functionL' t)) | h'<-[0..h]]Remember how Haskell separates lists, when you perform this (h:t) pattern match, it assigns the first element to h, then the rest of the elements to t, so this is your types:
h :: Int t :: [Int]The easiest way to do this (and probably the most Haskell-esque) is to use map (the foldl1 is just used to put it all together from recursion):
functionL (x:xs) = let restList = functionL xs in foldl1 (++) $ map (\v -> map (\lst -> v : lst) restList) [0..x]That's untested, but it should put you on the right track.
Wow I changed my sig!
#3
Posted 16 February 2011 - 11:49 AM
You made a little mistake on the 2nd line :) :
but it works nice, it's really what I needed, thank you! My Haskell skill is not so good as yours so I still have to understand the third line. Bye.
functionL [] = [] functionL [x] = [[0..x]] functionL (x:xs) = let restList = functionL xs in foldl1 (++) $ map (\v -> map (\lst -> v : lst) restList) [0..x]
but it works nice, it's really what I needed, thank you! My Haskell skill is not so good as yours so I still have to understand the third line. Bye.
#4
Posted 16 February 2011 - 02:16 PM
Oh no sir, that will not work. This is my output for that function from ghci:
*Prog> functionL [4,2,3] [[0,0,0,1,2,3],[0,1,0,1,2,3],[0,2,0,1,2,3],[1,0,0,1,2,3],[1,1,0,1,2,3],[1,2,0,1,2,3],[2,0,0,1,2,3],[2,1,0,1,2,3],[2,2,0,1,2,3],[3,0,0,1,2,3],[3,1,0,1,2,3],[3,2,0,1,2,3],[4,0,0,1,2,3],[4,1,0,1,2,3],[4,2,0,1,2,3]]You want this instead:
functionL [x] = [[y] | y <- [0..x]]That will work much better.
*Prog> functionL [4,2,3] [[0,0,0],[0,0,1],[0,0,2],[0,0,3],[0,1,0],[0,1,1],[0,1,2],[0,1,3],[0,2,0],[0,2,1],[0,2,2],[0,2,3],[1,0,0],[1,0,1],[1,0,2],[1,0,3],[1,1,0],[1,1,1],[1,1,2],[1,1,3],[1,2,0],[1,2,1],[1,2,2],[1,2,3],[2,0,0],[2,0,1],[2,0,2],[2,0,3],[2,1,0],[2,1,1],[2,1,2],[2,1,3],[2,2,0],[2,2,1],[2,2,2],[2,2,3],[3,0,0],[3,0,1],[3,0,2],[3,0,3],[3,1,0],[3,1,1],[3,1,2],[3,1,3],[3,2,0],[3,2,1],[3,2,2],[3,2,3],[4,0,0],[4,0,1],[4,0,2],[4,0,3],[4,1,0],[4,1,1],[4,1,2],[4,1,3],[4,2,0],[4,2,1],[4,2,2],[4,2,3]]
Wow I changed my sig!
#5
Posted 16 February 2011 - 03:43 PM
Ah yes sorry, I didn't post the correct version I was using, I used:
This will also work correctly. Many thanks for the function!
functionL :: [Int] -> [[Int]] functionL [] = [[]] functionL (x:xs) = let restList = functionL xs in foldl1 (++) $ map (\v -> map (\lst -> v : lst) restList) [0..x]
This will also work correctly. Many thanks for the function!
1 user(s) are reading this topic
0 members, 1 guests, 0 anonymous users


Sign In
Create Account

Back to top









