I am new to SML and I am having trouble understanding what are arguments and what is being passed to the inner function in this code.
fun print_mat mat =
let
val _ = (Array.foldl (
fn (arr, _) =>
let val _ = (print_arr arr) in () end
) () mat)
in () end;
Which is meant to be used in:
val mat =
Array.fromList[
(Array.fromList [0, 1, 1, 0, 1]),
(Array.fromList [1, 0, 1, 0, 0])
]
val _ print_mat mat
What I am failing to see is how the arr
gets selected from my mat
and used inside the closure function.
foldl
does something more than apply fn (arr, _) => ...
to every element. It accumulates a result, which in your case is discarded with the wildcard pattern, _
, in favor of the unit value, ()
. So, as Andreas Rossberg points out, you're not actually accumulating anything, or even generating any result value, so Array.app
is better suited.
To understand what
fun print_mat mat = Array.app print_arr mat
does, you can look at its implementation:
fun app f a =
let val a = from_array a
val stop = length_ a
fun lr j = if j < stop then (f(sub_ a j); lr (j+1))
else ()
in lr 0 end
Meaning, it calls f
(in your case print_arr
) on the 0th row of a
(in your case mat
), then on the 1st row, then on the 2nd until there are on more rows. When there are no more rows, return ()
. In the meantime, you have done nothing superfluous such as accumulate some value, since it will always be ()
that you return when done anyway.
I wonder if you have seen that Array2 exists. It should be pretty ideal for matrices.
As for understanding folding, see ML for the Working Programmer, ch. 5: Functions and infinite data.
I recommend that you understand folding in a list context first.
This is also what's best covered in learning material.