【问题标题】:Ocaml error lists higher-order functionOcaml错误列出高阶函数
【发布时间】:2018-06-26 15:53:08
【问题描述】:

我正在尝试编写一个高阶函数 pick,它选择函数 f 输出为 true 的元素,然后将它们的值输出到列表中。

例如:

#let f a = if a>8 then true else false;;
pick [1;3;4;9;12;22] f;;
- : int list = [9;12;22]

到目前为止,我编写了这段代码,但它不起作用:

let rec pick f list =
    let p1 = f list in
        if (List.hd(p1)==true)
            then List.hd(p1)::pick List.tl(p1)
        else pick  List.tl(p1)

错误:此表达式的类型为 'a list 但是需要一个类型为 'b -> bool#

的表达式

我怎样才能更正它以便它适用于列表?

【问题讨论】:

    标签: ocaml


    【解决方案1】:

    以下是您的代码存在的一些问题。

    • 您正在定义pick f list,但将其称为pick [list] f。确保你的论点顺序是一致的。 => 这是导致您收到错误消息的原因。
    • 正如 Nate C-K 所说。您不能在整个列表上调用 f,而只能在列表的元素上调用。
    • 请勿使用List.hdList.tl,除非您已经测试过您的列表是否为空。
    • 不要将 == 用于结构相等,不要将相等与布尔值一起使用。
    • if a>8 then true else false 应仅替换为 a>8

    【讨论】:

      【解决方案2】:

      使用表达式f list,您将列表list 传递给函数f,这不是您所说的您想要做的。您只想在列表的开头调用f

      通常在这种情况下,OCaml 程序员会使用模式匹配来解构列表,如下所示(我还没有测试过这段代码):

      let rec pick f list =
        match list with
        | [] -> []
        | h::t -> if f h then h :: pick f t
                         else pick f t
      

      【讨论】:

      • 非常感谢您的回答,我用模式匹配完成了一切,我认为它有效。
      【解决方案3】:

      List 模块已经包含了解决方案,它是函数 filter

      let f a = a > 8;;
      List.filter f [1;3;4;9;12;22];;
      - : int list = [9;12;22]
      

      该函数在列表上进行迭代,将验证给定谓词的元素存储在累加器中并返回它。

      标准库包含很多标准方法,如filter,建议先看文档,大部分问题都可以通过这些函数解决。

      列表模块的 Inria 文档:

      https://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html

      【讨论】:

      • 这个答案为您提供了另一种方式来做您想做的事。如果您只想对您的代码进行评论,请查看 PatJ 的回复
      猜你喜欢
      • 1970-01-01
      • 2015-09-22
      • 2010-12-31
      • 2014-06-07
      • 1970-01-01
      • 2013-05-08
      • 2013-05-07
      • 1970-01-01
      • 2015-09-19
      相关资源
      最近更新 更多