Converting Data to Strings (Debug Printing)
Primitive types in the
Standard Basis Library
have toString
defined for them as part of modules for those types.
For example, see the toString
functions for
int,
real, and
word.
For container types, like list and array, Mitchell provides additional libraries as below.
Mitchell’s libraries for graphs, matrices, etc., include toString
support
in those modules.
Basic Usage
In the examples below, we show you how to print structures that are filled with
integers. For other types, you will need to create the module using that type
and the toString
function for that type.
List of Integers
structure T = ListToString(struct type t = int; val toString = Int.toString end)
val lst = [1,2,3]
val _ = print (T.toString lst ^ "\n")
This prints
[1,2,3]
Arrays of Integers
(* Create the structure. *)
structure T = ArrayToString(struct type t = int; val toString = Int.toString end)
val arr = Array.fromList [1,2,3]
val _ = print (T.toString arr ^ "\n")
This prints
Array.fromList [1,2,3]
Pairs and Tuples
In order to print tuples, the library has to be told how to print each component of the tuple. Because this can be verbose, it is easier to read if you give a name to each intermediate structure.
(* Name the intermediate structures. *)
structure IntToString = struct type t = int; val toString = Int.toString end
structure RealToString = struct type t = real; val toString = Real.toString end
(* Create the module for printing pairs. *)
structure T = PairToString(struct structure S1 = IntToString; structure S2 = RealToString end)
(* Print a pair. *)
val pair = (42, 1.5)
val _ = print (T.toString pair ^ "\n")
This prints
(42, 1.5)
Lists of Arrays of Integers
These modules can be combined to create functions for printing lists of lists, lists of arrays, etc. In this example, we show how to print a list of arrays of integers.
structure A = ArrayToString(struct type t = int; val toString = Int.toString end)
structure L = ListToString(struct type t = int array; val toString = A.toString end)
val data = List.map Array.fromList [[1,2,3],[4,5],[6,7,8,9]]
val _ = print (T.toString arr ^ "\n")
This prints
[Array.fromList [1,2,3],Array.fromList [4,5],Array.fromList [6,7,8,9]]
Monomorphic Data Structures
Mitchell has support for the monomorphic data structures from Standard ML, which are containers that are specialized to contain only one type. It is unnecessary to use the monomorphic variants of data structures in Mitchell, because the compiler will optimize the generic variants to behave the same way. However, if you end up using one anyway, we provide some support for the converting monomorphic data structure to strings and printing them.
However, they have a different pattern of use than the generic structures that are described above. To create the module, you must provide the corresponding monomorphic slice data structure, as in the example below.
structure T = MonoArrayToString(struct structure S = IntArraySlice; val elemToString = Int.toString end)
val arr = IntArray.fromList [1,2,3]
val _ = print (T.toString arr ^ "\n")
This prints
MonoArray.fromList [1,2,3]
Interface
Mitchell includes toString
support via the following modules, which can be
used as described in the examples above.
ArrayToString
Array2ToString
ArraySliceToString
ListToString
VectorSliceToString
VectorToString
PairToString
Tuple3ToString
Tuple4ToString
Additionally, Mitchell includes toString
support for monomorphic containers
via the following modules, which can be used as described in the examples above.
MonoArraySliceToString
MonoArrayToString
MonoVectorSliceToString
MonoVectorToString