I have the function:
map(map(fn x =>[x])) [[],[1],[2,3,4]];
Which produces:
val it = [[],[[1]],[[2],[3],[4]]]
I don't understand how this function works. Doesn't each map function need both a function and a list? It seems that there isn't enough arguments for this to actually execute.
If I run:
map(fn x =>[x]) [[],[1],[2,3,4]];
I get:
val it = [[[]], [[1]], [[2,3,4]]];
Which makes more sense to me, as it takes each element in the list, and wraps it in another list. But when I put another map on it, it changes the output. Can anyone explain this to me? Thank you!
You said:
Well, keep in mind than, in Standard ML (and, in general, all applicative languages), there is no such thing as a "function of n parameters", for "n" other than 1. However, functions of more than one parameter can be simulated in two ways:
As functions of a single parameter that is a tuple or record. The original intended parameters can be recovered in the function's body by means of projection from the tuple or record.
As functions of the first parameter that return a function of the remaining parameters.
With this in mind, we check
map's type in the REPL:(I use Poly/ML, not SML/NJ, but formatting issues aside, the output should be the same.)
No tuples, no records.
mapclearly takes the second approach to simulating a function of two parameters: it takes a function of type'a -> 'band returns another function of type'a list -> 'b list.Now, here is the catch: For any function
foo,map foois a function as well! Sincemapcan take any function as argument,map foois itself a perfectly legitimate argument formap. Which means thatmap (map foo)typechecks for any functionfoo. In particular, this is true ifval foo = fn x => [x].You said:
If it typechecks, it runs.
You said:
Let's refactor your code a little bit, without changing its meaning:
Now we can analyze what every function (
foo,bar,baz) does to its parameter:footakes a single elementxand wraps it in a list data constructor.bartakes a list of elements, wraps each element in a list data constructor, and returns a list with the resulting wrapped elements (a list of lists).baztakes a (super)list of (sub)lists of elements, appliesbarto every sublist, and returns a list with the results.Perform all of this manually to convince yourself that the result,
[[], [[1]], [[2], [3], [4]]], is indeed correct.