Search code examples
functional-programmingsmlfold

Elegantly printing 2d array in SML


I was studying some SML/NJ and I came through the following question to myself:

Given an Array2 grid which contains strings in each cell and in the end of each row a \n find a way to elegantly print the array (using folds and stuff like that)

My attempt was

 print (Array2.fold Array2.RowMajor (op ^) "" grid)

which printed all the rows in the correct order but each row was reversed.

If that was a list it would support foldl and foldr functions so the whole process would be trivial.

And the conventional way to print it is

fun printGrid i N M grid =
  if (i >= N) then ()
  else
    (
      let
        fun printRow j M =
          if (j >= M + 1) then ()
          else (print (Array2.sub(grid, i, j)); printRow (j+1) M)
      in
        printRow 0 M;
        printGrid (i + 1) N M grid
      end
    )

which is of course not so elegant!

Is there an elegant (one-line) way to achieve printing it correctly?


Solution

  • In your trial, you use (op ^), which does fn (x, ans) => x ^ ans. However, what you want is fn (x, ans) => ans ^ x such that the order of concatenation is reversed.

    val arr = Array2.fromList [["1", "2", "\n"], ["3", "4", "\n"]];
    fun myConcat (x, ans) = ans ^ x;
    print (Array2.fold Array2.RowMajor myConcat "" arr);
    12
    34
    val it = () : unit