我已经开始了解一些与currying相关的例子,但我仍然不满意我想要的currying概念。我知道currying可以用来做部分评估,但我不确定它在某些情况下会起作用。
我知道它在以下示例中是如何工作的:
fun funkyPlus x y = x*x+y;
所以,假设我们只传递x的参数,那么它等同于以下内容:
fun funkyPlus 3 = (fn x => fn y => x*x+y)3
最终返回
fn y => 9+y
现在,我正在尝试将此想法应用于内置函数foldl
。
我知道它的代码是:
fun foldl f b [] = b
|foldl f b (h::t) = foldl f f(h,b) t.
我的问题是,如果我们不将所有参数传递给foldl
(即我们只传递第一个参数,即函数('a*'b->'b)
),该怎么办?在我给出的第一个例子中,当只有一个参数传递给它时,看到函数如何工作是相当简单的。但是,当我只传递一个参数时,我很难看到foldl
如何工作。
帮助。
答案 0 :(得分:2)
这并不意味着你的想法:
fun funkyPlus 3 = (fn x => fn y => x*x*y)3
它定义了一个函数,该函数接受一个必须为3的参数,如果它是3则计算为RHS,否则为未定义。你的意思是:如果我们只为x提供一个参数,我们有以下内容:
funkyPlus 3
→ (fn x => fn y => x*x+y) 3
等等。
其次,您的foldl
:
fun foldl f b [] = b|foldl f b (h::t) = foldl f f(h,b) t;
^^^^^
Type clash: expression of type
'a * 'b
cannot have type
'c list
这是因为(h,b)
被解析为foldl
的第三个参数而不是f
的参数。将其括起来:
fun foldl f b [] = b|foldl f b (h::t) = foldl f (f(h,b)) t;
> val ('a, 'b) foldl = fn : ('a * 'b -> 'b) -> 'b -> 'a list -> 'b
现在,回答你的问题,ML可以告诉我们像foldl add
这样的表达式会有int -> int list -> int
类型。
但总的来说,可能有助于意识到功能应用程序完全是机械的。如果我们有这两个定义:
fun foldl f b [] = b
| foldl f b (h::t) = foldl f (f(h,b)) t;
add (x,y) = x + y;
然后var example = foldl add
将等同于:
fun example b [] = b
| example b (h::t) = example (h::t) (add(h,b)) t;
所做的一切都是add
替换了f
正文中的foldl
,仅此而已(尽管我已经冒昧取代foldl add
身体example
。
答案 1 :(得分:1)
第一步是将foldl
的顶级方程组转换为lambda表达式,使用案例分析,如下所示:
val rec foldl = fn f => fn b => fn lst =>
case lst of [] => b
| (h::t) => foldl f (f(h,b)) t
现在您可以使用与以前相同的逻辑。以函数fn (x, y) => x * y
为例,我们可以看到
val prod = foldl (fn (x, y) => x * y)
相当于
val prod = (fn f => fn b => fn lst =>
case lst of [] => b
| (h::t) => foldl f (f(h,b)) t) (fn (x, y) => x * y)
val prod = fn b => fn lst =>
case lst of [] => b
| (h::t) => foldl (fn (x, y) => x * y) ((fn (x, y) => x * y)(h,b)) t
哪个beta减少到
val prod = fn b => fn lst =>
case lst of [] => b
| (h::t) => foldl (fn (x, y) => x * y) (h * b) t
既然我们从第一个定义中知道prod
等同于foldl (fn (x, y) => x * y)
,我们可以将其替换为自己的定义:
val rec prod = fn b => fn lst =>
case lst of [] => b
| (h::t) => prod (h * b) t
如果我们愿意的话,我们可以在心理上将其转换回由等式定义的函数:
fun prod b [] = b
| prod b (h::t) = prod (h * b) t
这是关于你期望的,对吗?