# Multiplication table using a list comprehension

I have just started reading through Learn you a Haskell I got up to list comprehension and started to play around in GHCi, my aim was to make a times table function that takes a number n and an upper limit upperLimit and return a nested list of all the 'tables' up to n for example

> timesTable 2 12
[[1,2..12],[2,4..24]]


the actual function/list comprehension I came up with is

> let timesTable n upperLimit = [[(n-y) * x | x <- [1..upperLimit]] | y <- reverse [0..(n-1)]]


Any feedback on the above would be greatly appreciated as this is the first time I have really used a functional language, so if there is a better way or something I have missed please let me know.

• Note that reverse [0..(n-1)] (even though it isn't needed, as Nicolas' answer shows) could be written [(n-1),(n-2)..0]. Commented Jan 29, 2012 at 17:06

Your function could be simplified a little, and I find it helpful to define functions using declarations, since type signatures are really helpful (although admittedly your example is simple enough that it doesn't matter):

timesTable :: Int -> Int -> [[Int]]
timesTable n u = [[y * x | x <- [1 .. u]] | y <- [1 .. n]]


The key thing I noticed was that you were using n-y: it should be obvious that this part of the expression becomes the following values in each iteration of y: [n-(n-1), n-(n-2), ... n-0], which is just [1 .. n].

• Thanks, I had a feeling that there was something fishy and convoluted with what I had done, feeling a bit silly now because it is very obvious, am just reading the Types and Type Classes chapter which covers declarations, cheers
– T I
Commented Jan 29, 2012 at 15:37
• We all have silly moments :-) I'm glad I could help! Commented Jan 30, 2012 at 2:18
• Is there a specific reason you chose Int rather than Integer or a polymorphic type? Commented Feb 9, 2012 at 23:57
• Oh, not really. You'd choose Int over Integer if you were interested in efficiency, and your numbers aren't too big. You'd choose Integer for unbounded precision, and you'd use a Num class constraint if you wanted to stay flexible (at the cost of having to pass a dictionary around). Commented Feb 10, 2012 at 18:46

We need no stinkin' list comprehensions. And multiplication is overrated as well...

timesTable n = scanl1 (zipWith (+)) . replicate n . enumFromTo 1