smlsmlnjmlton

How to proper read this SML function that uses foldl?


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.


Solution

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