我正在尝试定义一个在 SML 中包含一个元组的函数包装器。
fun curry f = fn (x, y) z => f x y z;
给我错误
应用于模式的非标识符。
我是 ML 新手,不知道为什么模式匹配fn
不起作用。
我怎样才能使这项工作?
我正在尝试定义一个在 SML 中包含一个元组的函数包装器。
fun curry f = fn (x, y) z => f x y z;
给我错误
应用于模式的非标识符。
我是 ML 新手,不知道为什么模式匹配fn
不起作用。
我怎样才能使这项工作?
我正在尝试定义一个在 SML 中包含一个元组的函数包装器。
fun curry f = fn (x, y) z => f x y z;
我怎样才能使这项工作?
SML 中的闭包不允许多个参数,但您可以嵌套它们。
curry
通常所做的是采用一个通常接受元组的函数,f
而(x, y)
不是返回一个修改后的函数,该函数分别接受x
and 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
andy
并返回一个修改后的函数,该函数接受(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
。例如,您可以将 anuncurry_twice
转换f x y z
为(uncurry_twice f) ((x, y), z)
,或将 anuncurry3
转换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