In Haskell I've defined a multiplication-table generator function like so:
multTable :: [[Int]]
multTable=map (\b -> map (b*) [1..12]) [1..12]
Which outputs...
[[1,2,3,4,5,6,7,8,9,10,11,12],
[2,4,6,8,10,12,14,16,18,20,22,24],
...[12,24,36,48,60,72,84,96,108,120,132,144]]
...and if you squint your eyes, this looks like multiplication tables for 1..12. So far so good ... now I've tried to make it point-free, thinking it should be pretty easy with composition. So I'm taking small steps and I believe that I've gotten partway there since I can do this:
map ($ 4) $ map (*) [1..12]
...which gives me:
[4,8,12,16,20,24,28,32,36,40,44,48]
Looking at this, the second map gives [a->a], which specifically here is a list of functions that multiply the values 1 through 12 by some number. The first map evaluates each of these functions providing them with the value 4, in turn producing the [4,8..] line.
I'm not necessarily expecting the pointfree version to be shorter, more concise or even more readable. As a Haskell newbie, I'm just looking to understand how it could be accomplished.
There's a tool called pointfree on hackage, which helps you tremendously (see also the wiki). It creates the following version:
multTable = map (flip map [1..12] . (*)) [1..12]
How do we get there? Well, lets move operators a little bit and try to apply flip
on your function till we get something similar:
multTable = map (\b -> map (b*) [1..12]) [1..12]
= map (\b -> map ((*) b) [1..12]) [1..12] -- change to prefix notation
= map (\b -> flip map [1..12] ((*) b) [1..12] -- flip map
= map (\b -> flip map [1..12] . (*) $ b) [1..12] -- associativity
= map (flip map [1..12] . (*)) [1..12] -- eta-reduction
Note that we only need to focus on \b -> map (b*) [1..12]
.
That being said, the pointfree version feels a little bit contrived. After all, you want a table, and Benjamin's shows a rather nice way to create one: list comprehensions:
multTable = [[x * y | x <- [1..12]] | y <- [1..12]]
This version is easier to read and more obvious to the reader, but then again, you probably thought that this would happen:
I'm not necessarily expecting the pointfree version to be shorter, more concise or even more readable.