我已经开始了解一些与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
如何工作 .
救命 .
2 回答
它定义了一个函数,该函数接受一个必须为3的参数,如果它是3则计算其RHS,否则是未定义的 . 你的意思是:如果我们只提供x的参数,我们有以下内容:
等等 .
foldl
中有错误:这是因为
(h,b)
被解析为foldl
的第三个参数,而不是f
的参数 . 用括号括起来:现在,回到你的问题,ML可以告诉我们像
foldl add
这样的表达式会有类型int -> int list -> int
.但总的来说,它可能有助于认识到功能应用程序是完全机械的 . 如果我们有这两个定义:
然后
var example = foldl add
将等同于:所有已经完成的事情是
add
已经在foldl
的正文中替换了f
,仅此而已(尽管我已经冒昧地用身体中的example
替换foldl add
) .第一步是将
foldl
的顶级方程组转换为使用案例分析的lambda表达式,如下所示:现在您可以使用与以前相同的逻辑 . 以函数
fn (x, y) => x * y
为例,我们可以看到相当于
哪个beta-reduces来
哪个beta减少到
既然我们从第一个定义知道
prod
等同于foldl (fn (x, y) => x * y)
,我们可以将它替换为它自己的定义:然后,如果我们愿意,我们可以在心理上将其转换回由等式定义的函数:
这是关于你期望的,对吗?