【问题标题】:List Recursion in OcamlOcaml 中的列表递归
【发布时间】:2018-09-11 11:20:45
【问题描述】:

这就是我想要实现的,通过 recursion 返回一个值低于给定值的列表:

# list_below 3 [7; 1; 0; 3];;
   - : int list = [1; 0]
# list_below 1 [-7; 1; 0; 3];;
   - : int list = [-7; 0]
# list_below 9.0 [4.2; 3.6; 5.0; 12.8];;
   - : float list = [4.2; 3.6; 5.0]

这是我到目前为止所写的,它似乎没有返回任何内容。

let rec list_below thresh lst = 
 if List.hd lst > thresh then [] else
  List.hd lst :: list_below thresh (List.tl lst);;
;;

你能告诉我我的代码有什么问题吗?

【问题讨论】:

    标签: recursion ocaml


    【解决方案1】:

    问题应该是杰弗里为你指出的。

    你的问题说你想实现list_below,但你的代码显示list_above。我会在这里坚持list_below

    如果您使用pattern matching,Ocaml 中的

    递归函数 可以非常直观地制作。例如,下面的代码应该可以工作:

    let rec list_below thresh lst =
      match lst with
      | [] -> []
      | hd :: tl -> if hd < thresh then hd :: (list_below thresh tl)
                else list_below thresh tl;;
    

    【讨论】:

    • 顺便说一句,如果您只是将您的if List.hd lst &gt; thresh then [] 更改为if List.hd lst &gt; thresh then list_below thresh (List.tl lst),则会因为不考虑空列表而引发错误。
    • 我不确定这是否会被视为折叠。没有蓄能器。但是,如果您确实希望代码与您的问题中的代码相似,则可以在比较 List.hd 的值之前添加一个 if 困境来检查空列表,以避免引发上述评论中所述的错误。
    【解决方案2】:

    如果第一个值高于阈值,您的代码将始终返回一个空列表。这不可能。一方面,它与您的第一个示例不一致。

    【讨论】:

      【解决方案3】:

      您可以尝试使用List.filter。由于您想获取小于所提供值的值列表,因此 filter 应该做您想做的事情。

      这是过滤器的文档:

      val filter : ('a -> bool) -> 'a list -> 'a list
      
      filter p l returns all the elements of the list l that satisfy the predicate p. The order of the elements in the input list is preserved.
      

      你需要的是提供一个谓词 p。谓词是一个函数,它接受一个元素并返回一个布尔值。过滤器将采用此谓词并应用于列表中的每个值。如果谓词对该元素返回 true,则该元素将被添加到结果列表中。

      所以在你的情况下,list_below 应该是

      let list_below thresh lst =
          List.filter (fun elem -> elem < thresh) lst
      

      更多操作列表,请查看 Real World OCaml 中的 chapter

      【讨论】:

      • 他强调他需要用递归来实现这个功能。我猜filter 不会成功。
      猜你喜欢
      • 2019-10-04
      • 1970-01-01
      • 2014-12-09
      • 1970-01-01
      • 2017-08-14
      • 2012-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多