"Карри" из кортежа в SML

Я пытаюсь определить оболочку функции, которая карри кортеж в SML.

fun curry f = fn (x, y) z => f x y z;

Дает мне ошибку

Неидентификатор применяется к шаблону.

Я новичок в ML и не уверен, почему шаблон соответствует fn не работает

Как я мог сделать эту работу?

1 ответ

Решение

Я пытаюсь определить оболочку функции, которая карри кортеж в SML.

fun curry f = fn (x, y) z => f x y z;

Как я мог сделать эту работу?

Замыкания в SML не допускают множественных аргументов, но вы можете вместо них вложить их.

Какие curry обычно это взять функцию f который обычно принимает кортеж (x, y) и вместо этого возвращает измененную функцию, которая принимает x а также y по отдельности. Вот несколько эквивалентных способов определения curry:

fun curry f x y = f (x, y)
fun curry f x = fn y => f (x, y)
fun curry f = fn x => fn y => f (x, y)
val curry = fn f => fn x => fn y => f (x, y)

Его противоположность, uncurry вместо этого берет функцию f это занимает x а также y отдельно и возвращает модифицированную функцию, которая принимает (x, y), Вот один из способов написать uncurry:

fun uncurry f (x, y) = f x y

Это легко смешать два.

Один из способов исправить написанную вами функцию, чтобы она компилировалась, - вставить дополнительную => fn:

fun what_is_this f = fn (x, y) => fn z => f x y z
                            (* ^- there *)

Прежде чем дать ему имя, давайте проанализируем, что он делает. Он имеет тип подписи:

fn : ('a -> 'b -> 'c -> 'd) -> 'a * 'b -> 'c -> 'd
                  (* now a tuple -^    ^- still curried *)

это означает, что он принимает функцию трех аргументов карри (x, y а также z) и возвращает модифицированную функцию, где первые два аргумента теперь находятся в кортеже (неиспользуемые), а третий все еще каррируется. Это действительно менее общая версия uncurry, Более понятный способ написания:

fun what_is_this f (x, y) z = f x y z

Если вы используете uncurry на функции трех аргументов вы получаете тот же эффект, но вы не можете использовать what_is_this на что-нибудь с двумя аргументами карри. Так что я бы сказал, что это менее полезный вариант uncurry,

Однако есть и другие, более полезные варианты curry / uncurry, Например, вы могли бы сделать uncurry_twice что преобразует f x y z в (uncurry_twice f) ((x, y), z) или uncurry3 что преобразует f x y z в (uncurry3 f) (x, y, z):

fun uncurry_twice f = uncurry (uncurry f)
fun uncurry3 f (x, y, z) = f x y z
Другие вопросы по тегам