Функции и величины языка ML
> fun fact n = if n = 0 then 1 else n * fact(n - 1); val fact = fn: int -> int
Зарезервированное слово fun в ML вводит объявление функции.
Идентификатор, следующий за fun, считается именем функции; за именем функции перечисляются параметры. Перечень параметров замыкается знаком «равно». После знака «равно» записывается тело функции.Система ML предоставляет объявление возвращаемой величины и типа этой величины. В данном примере функцией является fact, ее величиной считается fn с типом int -> int, который означает, что функция fact отображает из области определения целых чисел в область значений целых чисел. Действительно, можно задать объявление типа функции fact и типа ее параметра в виде:
> fun fact (n: int): int = if n = 0 then 1 else n * fact (n - 1);
val fact = fn: int -> int
После объявления функция может быть вызвана:
> fact 7;
val it = 5040 : int
Среда ML предоставляет возвращаемое значение и его тип (it — это имя вычисляемого выражения).
Правило вычислений в ML, по сути, такое же, как и в Scheme: fact задает вычисление функции, которое применяется к 7, тип аргумента должен совпадать с типом параметра функции. Функция вызывается, ее возвращаемое значение печатается вместе с типом. В ML не нужна функция quote (как в языке Scheme) для предотвращения вычислений, поскольку данные отличны от программ. В ML круглые скобки почти не употребляются, так как система способна распознать смысл элементов, основываясь на их позиции.Величины в ML можно определять с помощью ключевого слова val:
> val Pi = 3.14159;
val Pi = 3.14159 : real
Арифметические операции в ML записываются в инфиксной форме, так же, как в C или Ada. Этим язык отличается от унифицированной префиксной нотации для семейства Lisp. В итоге в ML появляются проблемы ассоциативности и приоритетности.
Конечно, язык ML придерживается стандартных математических соглашений по поводу стандартных математических операций. К примеру, 2 + 3 * 4 означает 2 + (3 * 4). В ML с помощью ключевого слова op можно задать префиксную форму записи, поэтому 2 + 3 * 4 можно записать так:
> op + (2 , op * ( 3,4)); val it = 14 : int
Бинарные арифметические операции в качестве аргументов принимают пары целых чисел. Типы этих пар являются элементами декартового произведения типов или кортежем int * int:
634 |
Глава 20. Функциональное программирование |
> (2,3); val it = (2,3) : int * int > op +; val it = fn : int * int -> int |