Sml 毫升;复合函数n次
如何在ML中合成函数fn次 复合两次;f(外汇) 复合三次;f(f(fx))) 复合n次;f(f(f…(fx‘‘‘‘‘‘‘‘‘)’) 我试过了Sml 毫升;复合函数n次,sml,ml,Sml,Ml,如何在ML中合成函数fn次 复合两次;f(外汇) 复合三次;f(f(fx))) 复合n次;f(f(f…(fx‘‘‘‘‘‘‘‘‘)’) 我试过了 fun composite f g = let h x = f(g x) in h end; fun repeat f n = if n = 0 then x else composite f repeat(f (n - 1)); 谢谢你你的想法几乎是正确的。你可以用咖喱来使它
fun composite f g =
let h x = f(g x)
in h end;
fun repeat f n =
if n = 0 then x
else composite f repeat(f (n - 1));
谢谢你你的想法几乎是正确的。你可以用咖喱来使它们起作用:
fun composite f g x = f(g(x));
SML推断其类型为:
val composite = fn : ('a -> 'b) -> ('c -> 'a) -> 'c -> 'b
这对构图来说是完全正确的。函数应用程序是左关联的,因此
composite f g x
解析为
(composite f g) x
因此,函数定义的含义是将函数(复合f g)
应用于参数x
。当然,其含义是返回值f(g(x))
您可以测试它:
fun square x = x*x
fun increment x = x + 1
val h = composite increment square
然后,例如,h5
按预期计算为26
类似的调整适用于第二个定义。它可以开始:
fun repeat f n x =
因为这看起来像是家庭作业,我将把细节留给你,但是你目前的尝试非常接近于正确的解决方案
说到这里,您应该知道composition是SML中的一个内置操作符,用小写的
o
表示,并且(op o)
可以在您的第二个定义中代替composite
,当您编写递归函数时,将问题划分为一般的递归情况,以及不需要递归的基本情况。例如,将一个函数自身组合n次听起来像是基本情况,可能是在n=0或n=1时(两者都可以工作;我会继续讨论)
我鼓励模式匹配,但当递归整数时,if-then-else看起来也一样简单。无论如何,所有的例子都是用这两种风格写的。简单的骨架可能是:
fun repeat f n =
if n = 0
then ?
else ?
fun repeat f 0 = ?
| repeat f 1 = ?
| repeat f n = ?
关于返回函数的函数
我想这里的一些困难是repeat
必须返回一个函数。从语法上讲,你可以通过各种方式来实现。正如John所建议的,您可以通过使用x
扩展repeat
来编写它:
fun repeat f n x =
if n = 1
then f x
else ...
fun repeat f 1 x = f x
| repeat f n x = ...
对此,自然但有点奇怪的解释是“repeat
是一个包含三个参数的函数;函数f
,必须应用的次数n
,以及f
的参数x
(?!)”
或者,你也可以这样写
fun repeat f n =
if n = 1
then (fn x => f x)
else ...
fun repeat f 1 = (fn x => f x)
| repeat f n = ...
这可能会被解释为“repeat
是一个接受两个参数的函数;函数f
及其必须应用的次数n
,并返回一个将f
应用于其参数n
次的函数。”
这些定义实际上是等价的。通过将描述转换为类型,您将看到:
val重复:('a->'a)->int->'a->'a
val重复:('a->'a)->int->('a->'a)
repeat
似乎是这两者的混合体n
最好被认为是“第二个参数”,而x
最好被认为是“我们返回的函数所使用的参数”
有了这个偏好和模式匹配的偏好,我建议的基础是:
fun repeat f 0 = ...
| repeat f 1 = f
| repeat f n = ...
因为(fnx=>fx)
和f
实际上是一个相同的函数
关于基情形和递归情形
你写道:
then x
中的x
类型错误,因为repeat f n
必须返回一个函数。见上文f
0次时的情况有点棘手。无论结果是什么,repeat f0
应该给出相同的结果,而不管f
。或者换句话说,f
不被应用,尽管repeat f0
确实需要返回一些东西o
操作符,这是Standard ML内置的composite
版本,我也更喜欢它:
composite f (repeat f (n-1))
f o repeat f (n-1)
关于标准ML中的括号,您需要了解的是:您主要将它们添加到分组中。当您编写composite f repeat(f(n-1))
时,您要说的是:“composite
是一个三参数函数,它接受f
,repeat
和f(n-1)
作为参数,f
是一个接受整数作为参数的函数。”
当你真正想说的是“composite
接受f
和用自身n
组合f
的结果–1次,然后组合这些。”当你来自那些期望函数调用看起来像foo(arg1,arg,arg3)的语言时,这是一个典型的错误
有人认为这会转化为foo(arg1 arg arg3)
而实际上您需要foo arg1 arg2 arg3
。在标准ML中,此括号强制将arg1
视为一个函数,并将其应用于arg2
和arg3
,并将foo
应用于该函数的结果。哎呀我喜欢你的一些答案有多详细。他们提供了很多信息供学生思考。非常感谢。我对n=0分支有一个问题,但现在很清楚我做错了什么。谢谢。我现在明白了括号的用法。
composite f (repeat f (n-1))
f o repeat f (n-1)