что такое карри и невосприимчивость в функциях высокого порядка в ML - PullRequest
6 голосов
/ 06 декабря 2011
fun curry f x y = f (x, y); 
fun uncurry f (x, y) = f x y; 
fun compose (f, g) x = f (g x);

Я понимаю составную функцию, но не совсем понимаю карри и невосприимчивость в ML. Кто-нибудь может объяснить это?

Кроме того, что означают следующие две строки?

(1) compose (compose, uncurry compose)
(2) compose (uncurry compose, compose)

1 Ответ

11 голосов
/ 06 декабря 2011

Если вы посмотрите на типы, то вы ясно увидите, что делают curry и uncurry.

Помните, что можно определить функцию, которая принимает свои аргументы как один большой кортеж или как несколько аргументов (в действительности это становится «цепочкой» функций, каждый из которых принимает 1 аргумент, см. wiki ):

fun foo (a,x) = a*x+10
fun bar a x = a*x+20

Разница отчетливо видна в их типах:

val foo = fn : int * int -> int
val bar = fn : int -> int -> int

Функция curry "преобразует" функцию, которая принимает свои аргументы в виде кортежа, в "цепочку" функций, каждая из которых принимает 1 из аргументов. Это особенно удобно, когда мы хотим составить ряд функций, некоторые из которых были частично применены с аргументами. Посмотрите, как меняется тип foo:

- curry foo;
val it = fn : int -> int -> int

Теперь мы можем попытаться скомпоновать две функции:

- (curry foo 5 o bar 1) 4;
val it = 130 : int

Первые 4 применяются к bar 1 в качестве аргумента x, затем результат этого вычисления (bar 1 4) дается в качестве x аргумента для foo.

Очевидно, uncurry используется для обратного процесса:

- uncurry bar;
val it = fn : int * int -> int
...