填写管道的骨架,使用List.fold_left获取OCaml函数
val pipe : ('a -> 'a) list -> ('a -> 'a)
这样pipe [f1;...;fn]
(其中f1,...,fn
是函数!)返回一个函数f
,对于任何x
,我们f x
返回结果fn(...(f2(f1 x)))
同样,您的任务是填写折叠函数f
和基本案例的相应值。
实现该功能后,您应该在OCaml提示符下获得以下行为:
# pipe [] 3;;
- : int = 3
# pipe [(fun x -> x+x); (fun x -> x + 3)] 3 ;;
- : int = 9
# pipe [(fun x -> x + 3);(fun x-> x + x)] 3;;
- : int = 12
以下是您需要填写的代码:
let pipe fs =
let f a x = failwith "to be implemented" in
let base = failwith "to be implemented" in
List.fold_left f base fs
有人可以帮我这个吗?
答案 0 :(得分:2)
在你给出的骨架中,pipe
只接受一个参数。根据管道类型(('a -> 'a) list -> 'a list
),您知道此参数的类型为('a -> 'a) list
,并且您应该返回('a -> 'a)
类型的值。
现在List.fold_left
的类型的格式为('b -> 'c -> 'b) -> 'b -> 'c list -> 'b
。但是你知道:
它应返回'a -> 'a
类型的值,因此'b
将('a -> 'a)
实例化
第三个参数的类型为('a -> 'a) list
,因此'c list
将为('a -> 'a) list
:'c
将再次('a -> 'a)
实例化。< / p>
你可以得出结论,你会在专业类型中使用List.fold_left
(是的,它是满口的)
(('a -> 'a) -> ('a -> 'a) -> ('a -> 'a)) -> ('a -> 'a) -> ('a -> 'a) list -> ('a -> 'a)
简短地说:如果管道必须返回一个函数并获取一个函数列表,那么base
本身必须是一个函数,而f
必须带两个函数并返回一个函数。
base
应该是哪个函数?如果base
为空列表,则会返回fs
,因此base
应具有pipe []
预期的行为。
f a x
应如何合并a
和x
这两个函数'a -> 'a
,并返回单个函数'a -> 'a
?我会让你在这里找到答案。但你想要拥有以下平等的直觉:
f(pipe [f1; f2])f3 = pipe [f1; F2; F3]
(它适用于任何列表,而不仅仅是[f1; f2]
,但这个例子就足够了)。通过计算pipe [f1; f2]
和pipe [f1; f2; f3]
的含义之间的关系,您将能够定义组合函数f
。
请注意,您可以从以下不同的骨架开始以非常的方式编写pipe
函数:
let pipe fs x =
let f a x = failwith "to be implemented" in
let base = failwith "to be implemented" in
List.fold_left f base fs
在这种情况下,pipe
接受两个参数,一个类型为('a -> 'a) list
,另一个类型为'a
,整个返回值应为'a
类型(一个值,而不是一个函数)。 f
获取函数('a -> 'a
)和值('a
)并返回一个值,而base
只是一个值(您可以选择哪一个?)。< / p>
我相信第二种方法稍微容易一点,但是如果你老师要求你使用第一个骨架,那可能是因为它会教你操作函数和构建函数的函数。
答案 1 :(得分:0)
您可能想先回答这些问题:
f
,a
和x
有哪些更好的名称,即这些变量的作用是什么?