Является ли оператор SML `o` полезным только для функций с одним аргументом?
Является ли составной оператор o
(например, val x = foo o bar
, где foo
и bar
- обе функции), применимы только к однопараметрическим функциям и/или функциям с равным числом аргументов? Если нет, то каков синтаксис, например, для составления foo(x,y)
с помощью bar(x)
.
Ответы
Ответ 1
Как уже сказал Майкл, да, SML имеет только одну функцию аргументов. Однако я хочу немного уточнить.
Следующая функция:
fun foo (x,y) = x + y
Имеет тип:
fn : int * int -> int
Это означает, что первый аргумент является кортежем из двух целых чисел. Таким образом, вы можете сделать что-то вроде:
(sign o foo) (4,~5)
Что даст вам то же самое, что sign (foo (4,~5))
.
Хорошо, но как насчет этого?
fun bar x y = x + y
Он имеет тип:
fn : int -> int -> int
Это означает, что бар фактически принимает только одно целое число и возвращает функцию. Поэтому вы не можете этого сделать:
(sign o bar) 4 ~5
Потому что bar возвращает функцию, а знак принимает целое число. Вы можете сделать это, хотя:
(sign o bar 4) ~5
Потому что bar 4
- это функция, которая добавляет 4 к числу.
Ответ 2
SML имеет только одну функцию аргумента; foo(x,y)
- это функция foo
, принимающая один аргумент, кортеж (x, y)
. Таким образом, нет необходимости в специальном обращении, и bar(x)
нужно будет возвратить кортеж соответствующего типа, чтобы составить его с помощью foo
.
Ответ 3
Я видел некоторый стандартный код ML (в частности, код Poly/ML Isabelle/Pure), который добавляет дополнительные операторы композиции в среду верхнего уровня, которые справляются с такой ситуацией. Например:.
fun (f oo g) x y = f (g x y)
fun (f ooo g) x y z = f (g x y z)
fun (f oooo g) x y z w = f (g x y z w)
Как правило, такие вещи следует использовать экономно (четыре или более o становится немного глупым), но он весьма полезен, имея по крайней мере oo
вокруг.