在你给出的骨架中,pipe
只接受一个参数。根据 pipe( ('a -> 'a) list -> 'a list
) 的类型,您知道该参数具有类型('a -> 'a) list
,并且您应该返回某个类型的值('a -> 'a)
。
现在的类型List.fold_left
是形式('b -> 'c -> 'b) -> 'b -> 'c list -> 'b
。但你知道:
它应该返回一个 type 的值'a -> 'a
,所以'b
将在('a -> 'a)
这里实例化
第三个参数是 类型的('a -> 'a) list
,所以'c list
会在('a -> 'a) list
这里:再次'c
将被实例化为('a -> 'a)
。
您可以得出结论,您将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 (管道 [f1; f2]) f3 = 管道 [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
接受两个参数,一个是 type ('a -> 'a) list
,另一个是 type 'a
,并且整个返回值应该是 type 'a
(一个值,而不是一个函数)。f
接受一个函数 ( 'a -> 'a
) 和一个值 ( 'a
) 并返回一个值,并且base
只是一个值(您可以选择哪个?)。
我相信第二种方法稍微简单一点,因为它不那么抽象,但是如果你的老师要求你使用第一个骨架,那可能是因为它会教你关于操作函数的知识,以及构建构建函数的函数。