Range Over Iterators in Standard ML
Our aim is to demonstrate the usage of Standard ML functions and iterators with various examples. Here’s the full source code translated into Standard ML.
First, we will define our List
type and necessary functions.
(* Define the List type and functions *)
datatype 'a element = Element of { value: 'a, next: 'a element option }
datatype 'a List = List of { mutable head: 'a element option, mutable tail: 'a element option }
fun createList () = List { head = NONE, tail = NONE }
fun push (List { head, tail }) value =
let
val new_elem = SOME (Element { value = value, next = NONE })
in
case tail of
NONE => (head := new_elem; tail := new_elem)
| SOME (Element { next, ... }) => (next := new_elem; tail := new_elem)
end
Let’s look at the List
type. In the above example, we have defined a push
function to add elements to the list. Now, let’s create a function that will return an iterator over the list.
(* Function to iterate over all elements in the list *)
fun all (List { head, _ }) yield =
let
fun aux NONE = ()
| aux (SOME (Element { value, next })) =
if yield value then aux next else ()
in
aux head
end
Here, we define an all
function that takes a list and a yield
function which is invoked for each element until early termination if needed.
Next, we’ll demonstrate generating Fibonacci numbers using a function that returns an iterator.
(* Fibonacci generator function *)
fun genFib yield =
let
fun aux a b =
if yield a then aux b (a + b) else ()
in
aux 1 1
end
This function genFib
will generate Fibonacci numbers indefinitely until yield
returns false
.
We will see how to use these iterators in practical scenarios.
(* Example usage *)
val lst = createList ()
val () = push lst 10
val () = push lst 13
val () = push lst 23
(* Print all elements in the list *)
val () = all lst (fn x => (print (Int.toString x ^ "\n"); true))
(* Collect all elements in a list *)
val allElements = ref []
val () = all lst (fn x => (allElements := !allElements @ [x]; true))
val () = print ("all: [" ^ String.concatWith " " (List.map Int.toString (!allElements)) ^ "]\n")
(* Print Fibonacci numbers less than 10 *)
val () = genFib (fn x => (if x >= 10 then false else (print (Int.toString x ^ "\n"); true)))
With the above code, you can manage elements in a custom list and generate Fibonacci numbers in Standard ML.
Let’s summarize the key points:
- Define List and element types: Custom types handling the list and element structure.
- Push function: Add elements to our list.
- Iterator function
all
: Iterate over elements in the list using a yielding function. - Fibonacci generator: Generate Fibonacci numbers using an iterative function and yield.
You can try running these code snippets on an SML interpreter to see how iterators work along with custom list management.
Now that we have explored iterators and custom lists in Standard ML, let’s dive deeper into more advanced topics in the language.