"Curry" 来自 SML 中的元组
"Curry" from tuple in SML
我正在尝试定义一个函数包装器,用 SML 柯里化元组。
fun curry f = fn (x, y) z => f x y z;
给我错误
Non-identifier applied to a pattern.
我是 ML 新手,不确定为什么 fn
中的模式匹配不起作用。
我怎样才能完成这项工作?
I am trying to define a function wrapper that curries a tuple in SML.
fun curry f = fn (x, y) z => f x y z;
How could I make this work?
SML 中的闭包不允许使用多个参数,但您可以将它们嵌套起来。
curry
通常做的是接受一个通常接受元组 (x, y)
的函数 f
而不是 returns 接受 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
,returns 是一个修改后的函数,取 (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
)和 returns 一个修改后的函数,其中前两个参数现在是在元组(未咖喱)中,第三个仍然是咖喱。这实际上是 uncurry
的不太通用的版本。更清晰的写法是:
fun what_is_this f (x, y) z = f x y z
如果对具有三个参数的函数使用 uncurry
,会得到相同的效果,但不能对具有两个柯里化参数的任何函数使用 what_is_this
。所以我想说这是 uncurry
的一个不太有用的变体。
然而 curry
/uncurry
还有其他更有用的变体。例如,您可以制作一个将 f x y z
转换为 (uncurry_twice f) ((x, y), z)
的 uncurry_twice
,或将 f x y z
转换为 (uncurry3 f) (x, y, z)
的 uncurry3
:
fun uncurry_twice f = uncurry (uncurry f)
fun uncurry3 f (x, y, z) = f x y z
我正在尝试定义一个函数包装器,用 SML 柯里化元组。
fun curry f = fn (x, y) z => f x y z;
给我错误
Non-identifier applied to a pattern.
我是 ML 新手,不确定为什么 fn
中的模式匹配不起作用。
我怎样才能完成这项工作?
I am trying to define a function wrapper that curries a tuple in SML.
fun curry f = fn (x, y) z => f x y z;
How could I make this work?
SML 中的闭包不允许使用多个参数,但您可以将它们嵌套起来。
curry
通常做的是接受一个通常接受元组 (x, y)
的函数 f
而不是 returns 接受 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
,returns 是一个修改后的函数,取 (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
)和 returns 一个修改后的函数,其中前两个参数现在是在元组(未咖喱)中,第三个仍然是咖喱。这实际上是 uncurry
的不太通用的版本。更清晰的写法是:
fun what_is_this f (x, y) z = f x y z
如果对具有三个参数的函数使用 uncurry
,会得到相同的效果,但不能对具有两个柯里化参数的任何函数使用 what_is_this
。所以我想说这是 uncurry
的一个不太有用的变体。
然而 curry
/uncurry
还有其他更有用的变体。例如,您可以制作一个将 f x y z
转换为 (uncurry_twice f) ((x, y), z)
的 uncurry_twice
,或将 f x y z
转换为 (uncurry3 f) (x, y, z)
的 uncurry3
:
fun uncurry_twice f = uncurry (uncurry f)
fun uncurry3 f (x, y, z) = f x y z