"Карри" из кортежа в 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