【问题标题】:List reverse Ocaml列出反向 Ocaml
【发布时间】:2020-06-25 22:34:36
【问题描述】:

我正在创建一个反转列表的函数。 我认为一切都很好,但编译器的意见不一样...... 这是代码:

let reverse list_ =
 let rec support list_ =
 match list_ with
 | [] -> []
 | hd :: tl -> support tl :: hd in
 let return = support list_ in return

错误是:

| hd :: tl -> support tl :: hd in

Error: This expression has type 'a list
   but an expression was expected of type 'a
   The type variable 'a occurs inside 'a list`

我的想法是到达列表的末尾,而不是从[] 构建一个新列表,添加最新的元素。

【问题讨论】:

    标签: functional-programming ocaml


    【解决方案1】:

    运算符:: 不是对称的。它在左侧接受一个列表元素,在右侧接受一个列表。在这个表达式中:

    support tl :: hd
    

    左边有一个列表(递归调用的结果),右边有一个列表元素。所以这是行不通的。

    【讨论】:

      【解决方案2】:

      错误告诉您support tl 的类型为'a list,而:: 运算符的工作方式如下:1 :: [2;3] = [1;2;3]。从概念上讲,您尝试做的是[3; 2] :: 1,这不是操作员的工作方式。

      如果您想在列表末尾附加hd,您需要使用@ 运算符(或append 函数):

      let reverse list_ =
        let rec support list_ =
          match list_ with
          | [] -> []
          | hd :: tl -> support tl @ [hd] in
        let return = support list_ in return
      

      现在的问题是时间复杂度,我们正在遍历每个元素的整个列表。为了解决这个问题,我们可以使用一个列表来累积元素:

      let reverse list =
        let rec support acc list_ =
          match list_ with
          | [] -> acc
          | hd :: tl -> support (hd :: acc) tl in
        let return = support [] list in return
      

      考虑到这一点,这段代码可能会被重写一点:

      • 表达式let return = support [] list in returnsupport [] list 相同
      • let some_fun some_val = match some_val with (* ... *) 可以写成let some_fun = function (* ... *) 完全省略some_val
      let reverse list =
        let rec support acc = function
        | [] -> acc
        | hd :: tl -> support (hd :: acc) tl in
        support [] list
      

      我猜想使用matchfunction 只是个人喜好问题。

      【讨论】:

      • 它有效,谢谢!但我不明白你做了什么...“| hd :: tl -> support (hd :: acc) tl”的意思是:“如果列表中有头部和尾部调用支持 (hd::acc )" 为什么你在后面设置一个 "tl"? “支持”只有 1 个参数...我没听懂
      • 我知道我可以使用“@”但我正在寻找一个自制的功能
      • @MichealRoss support 实际上有 2 个参数,我希望现在更清楚了!
      • OK 用“match”一切都清楚了,不用“match”用“function”?
      • support 有这种类型签名'a list -> 'a list -> 'a list,所以support (hd :: acc) tl 大致意思是“调用支持,hd :: acc 作为第一个参数,tl 作为第二个参数”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-24
      • 2011-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多