ocaml函数调用List.fold_left

时间:2012-10-26 08:14:31

标签: ocaml

填写管道的骨架,使用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

有人可以帮我这个吗?

2 个答案:

答案 0 :(得分:2)

在你给出的骨架中,pipe只接受一个参数。根据管道类型(('a -> 'a) list -> 'a list),您知道此参数的类型为('a -> 'a) list,并且您应该返回('a -> 'a)类型的值。

现在List.fold_left的类型的格式为('b -> 'c -> 'b) -> 'b -> 'c list -> 'b。但是你知道:

  1. 它应返回'a -> 'a类型的值,因此'b('a -> 'a)实例化

  2. 第三个参数的类型为('a -> 'a) list,因此'c list将为('a -> 'a) list'c将再次('a -> 'a)实例化。< / p>

  3. 你可以得出结论,你会在专业类型中使用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应如何合并ax这两个函数'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)

您可能想先回答这些问题:

  • 写一个对管道的调用示例,其中只使用基本案例。
  • 何时使用基本情况?
  • 基本案例的类型是什么?
  • fax有哪些更好的名称,即这些变量的作用是什么?