如何正确解读使用foldl的SML函数?arr参数传递逻辑存疑
arr is Passed in Your SML print_mat Function Hey there! Let's break down this code piece by piece so you can see exactly how arr gets picked up and used in the closure. I know SML's syntax can feel a bit verbose at first, so simplifying it will help make things clearer.
First, Let's Recap the Core Code
Your original function:
fun print_mat mat = let val _ = (Array.foldl ( fn (arr, _) => let val _ = (print_arr arr) in () end ) () mat) in () end;
And your example usage:
val mat = Array.fromList[ (Array.fromList [0, 1, 1, 0, 1]), (Array.fromList [1, 0, 1, 0, 0]) ] val _ = print_mat mat
Let's Simplify the Code First
A lot of the let val _ = ... in () end boilerplate is unnecessary here because we're only using side effects (printing) instead of returning a meaningful value. We can rewrite print_mat to be much cleaner:
fun print_mat mat = Array.foldl (fn (arr, _) => print_arr arr) () mat
This does exactly the same thing as your original code—just easier to read.
Now, How Does arr Get Selected?
Let's focus on Array.foldl, which is the key here:
Array.foldlis a function that iterates over every element in an array. For each element, it passes two things to the anonymous function you give it:- The current element of the array (this is your
arr!) - A "accumulator" value (we use
_here because we don't care about it—we're just usingfoldlto loop, not to build up a result)
- The current element of the array (this is your
- The second argument to
Array.foldlis()(the unit value), which is the initial value of the accumulator. Since we don't use the accumulator, this doesn't affect our code. - The third argument is
mat—the 2D array you pass toprint_mat.
Step-by-Step with Your Example
When you call print_mat mat:
Array.foldllooks at the first element ofmat: that'sArray.fromList [0, 1, 1, 0, 1]. It passes this element asarrto the anonymous function.- The anonymous function calls
print_arr arr, which prints this 1D array. - Next,
Array.foldlmoves to the second element ofmat:Array.fromList [1, 0, 1, 0, 0]. Again, this becomesarrin the anonymous function, andprint_arrprints it. - Once all elements are processed,
foldlreturns the final accumulator value (()), which we ignore since we only care about the printing side effect.
Why Does the Closure Have Access to arr?
The anonymous function fn (arr, _) => print_arr arr is a closure that captures the arr parameter passed to it by Array.foldl. Every time foldl processes a new element in mat, it creates a new binding for arr pointing to that element, and the closure uses that binding to call print_arr.
In short: arr is just each individual 1D array inside your 2D mat array, and Array.foldl handles looping through them and passing each one to your closure.
内容的提问来源于stack exchange,提问作者nico

