部分求值和柯里化
我已经开始理解一些与柯里化相关的示例,但我仍然对我想要的柯里化概念感到不舒服。我知道柯里化可用于进行部分评估,但我不确定它在某些情况下如何工作。
我知道它在下面的示例中是如何工作的:
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
将如何工作。
帮助。
I have begun to understand a few examples related to currying but I am still not comfortable with the concept of currying as I would like to be. I know that currying can be used to do partial evaluation but I am not sure how it would work in certain cases.
I know how it works in the example below:
fun funkyPlus x y = x*x+y;
so let's say we only pass an argument for x then it is equivalent to the following:
fun funkyPlus 3 = (fn x => fn y => x*x+y)3
which ends up returning
fn y => 9+y
Now, I am trying to apply this idea to the built in function foldl
.
I know the code for it is:
fun foldl f b [] = b
|foldl f b (h::t) = foldl f f(h,b) t.
My question is, what if we do not pass all the arguments to foldl
(i.e. we only pass it the first argument which is the function ('a*'b->'b)
). In the first example I gave, it was fairly simple to see how the function works when only one of the arguments is passed to it. However, I am having trouble seeing how foldl
would work when there is only one argument passed to it.
Help.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这并不意味着你的想法:
它定义了一个函数,该函数接受的参数必须为 3,如果该参数为 3,则计算其 RHS,否则未定义。你的意思是这样的:如果我们只提供 x 的一个参数,我们有以下结果:
<前><代码>funkyPlus 3
→ (fn x => fn y => x*x+y) 3
等等。
其次,您的
foldl
中存在错误:这是因为
(h,b)
被解析为foldl
的第三个参数,而不是f
的参数。将其括起来:现在,回到你的问题,机器学习可以告诉我们像
foldl add
这样的表达式将具有类型int ->;整数列表-> int
。但总的来说,认识到函数应用完全是机械的可能会有所帮助。如果我们有这两个定义:
那么
var example = Foldl add
就相当于这样:所做的就是将
add
替换为f 在
foldl
的主体中,仅此而已(尽管我冒昧地将foldl add
替换为主体中的example
)。This does not mean what you think:
It defines a function which takes an argument that must be 3, and which evaluates to its RHS if it is 3 and is undefined otherwise. What you mean to say is this: If we only provide an argument for x, we have the following:
and so forth.
Secondly, there is an error in your
foldl
:This is because
(h,b)
is parsed as the third argument tofoldl
and not as the argument tof
. Parenthesize it:Now, getting to your question, ML can tell us that an expression like
foldl add
would have typeint -> int list -> int
.But in general, it may help to realize that function application is entirely mechanical. If we have these two definitions:
then
var example = foldl add
would be equivalent to this:All that’s been done is that
add
has been substituted forf
in the body offoldl
, nothing more (although I have taken the liberty of replacingfoldl add
withexample
in the body).第一步是将
foldl
的顶级方程组转换为使用案例分析的 lambda 表达式,如下所示:现在您可以使用与以前相同的逻辑。以函数 fn (x, y) => 为例x * y,我们可以看到它
相当于
beta-reduces ,
我们
由于我们从第一个定义中知道
prod
相当于foldl (fn (x, y) => x * y)
,所以 beta-reduce 为 Now 可以将其替换为它自己的定义:然后,如果我们愿意,我们可以在心里将其转换回由方程定义的函数:
这就是您所期望的,对吧?
The first step is to turn your top-level set of equations for
foldl
into a lambda expression which uses case analysis, like so:Now you can use the same logic as before. Taking as an example the function
fn (x, y) => x * y
, we can see thatis equivalent to
which beta-reduces to
which beta-reduces to
Now since we know from our first definition that
prod
is equivalent tofoldl (fn (x, y) => x * y)
, we can substitute it into its own definition:We can then mentally convert this back to a function defined by equations if we like:
That's about what you'd expect, right?