4
\$\begingroup\$

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.

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jan 29, 2012 at 15:04
\$\endgroup\$
1
  • \$\begingroup\$ Note that reverse [0..(n-1)] (even though it isn't needed, as Nicolas' answer shows) could be written [(n-1),(n-2)..0]. \$\endgroup\$ Commented Jan 29, 2012 at 17:06

2 Answers 2

5
\$\begingroup\$

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].

answered Jan 29, 2012 at 15:23
\$\endgroup\$
4
  • \$\begingroup\$ 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 \$\endgroup\$ Commented Jan 29, 2012 at 15:37
  • \$\begingroup\$ We all have silly moments :-) I'm glad I could help! \$\endgroup\$ Commented Jan 30, 2012 at 2:18
  • \$\begingroup\$ Is there a specific reason you chose Int rather than Integer or a polymorphic type? \$\endgroup\$ Commented Feb 9, 2012 at 23:57
  • \$\begingroup\$ 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). \$\endgroup\$ Commented Feb 10, 2012 at 18:46
1
\$\begingroup\$

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

timesTable n = scanl1 (zipWith (+)) . replicate n . enumFromTo 1 
answered Feb 9, 2012 at 20:45
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.