Ленивые вычисления, например, могли бы
fun compare_lists [] [] = true
| compare_lists head::tail1 head::tail2 = compare_lists tail1 tail2
| compare_lists list1 Iist2 = false
fun tree_to_list Empty = []
| tree_to_listT(left, value, right) =
value :: append (tree_to_list left) (tree_to_list right)
Ленивые вычисления, например, могли бы происходить следующим образом (мы использовали сокращенные имена функций сmp и ttl, а многоточием обозначили очень большое поддерево):
cmp ttl T(T(Empty,4,Empty), 5, . . .)
ttl T(T(Empty,6,Empty), 5,...) =
cmp 5:: append (ttl T(Empty,4,Empty)) (ttl.. .)
5:: append (ttl T(Empty,6,Empty)) (ttl.. .) =
cmp append (ttl T(Empty,4,Empty)) (ttl.. .)
append (ttl T(Empty,6,Empty)) (ttl. ..) =
…
cmp 4:: append [] (ttl. . .)
6:: append [] (ttl. ..) =
false
Вычисления, выполняемые только по мере необходимости, позволили полностью избежать ненужного обхода правого поддерева. Чтобы достичь того же самого эффекта в языке, подобном ML, который использует жадные вычисления, придется применять специальные приемы.
Дополнительное преимущество ленивых вычислений состоит в том, что они подходят для интерактивного и системного программирования. Ввод, скажем, с терминала рассматривается просто как потенциально бесконечный список значений. При ленивых вычислениях, конечно, никогда не рассматривается весь список: вместо этого всякий раз, когда пользователь вводит значение, забирается первый элемент списка.
16.6. Исключения
Вычисление выражения в языке ML может привести к исключению. Существуют стандартные исключения, которые в основном возникают при вычислениях со встроенными типами, например при делении на ноль или попытке взять первый элемент пустого списка. Программист также может объявлять исключения, у которых могут быть необязательные параметры: