将Scheme转换为OCaml? ('列表vs'列表列表 - >'列表列表)

时间:2015-11-06 08:42:52

标签: scheme ocaml

(define min
   (lambda (l)
      (cond
         ((null? l) '())
         ((null? (cdr l)) (car l))
         (#t (let ((a (car l))
                   (b (min (cdr l))))
               (if (< b a) b a))))))

我正在尝试将前面的Scheme代码转换为OCaml代码中找到列表中最小的元素,到目前为止我有以下内容:

let minList x =
   match x with
   | [] -> []
   | hd::tl when tl = [] -> hd
   | hd::tl -> if minList tl < hd then minList tl else hd

但是,我收到一条错误消息“此表达式具有类型'列表,但表达式需要'a list list -> 'a list list类型。

我是函数式语言的初学者,非常感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

这与类型系统不同。

使用Scheme,该函数可以输出数字或空列表。

> (min `(1 2 3))
1

> (min `())
()

使用OCaml你不能,输出必须是同一类型。您可以在Real World Ocaml中了解有关类型推断的更多信息。

您不希望从空列表中返回一个int,您想要失败。

您可以使用选项类型,以便函数从空列表中输出None,从非空Some 'a输出'a list。 因此,函数的类型将是'a list -> 'a option

而且顺便说一句,案例| hd::tl when tl = [] -> hd可以简化为| [x] -> x。 与tl = []hd::tl = hd::[] = [hd]时一样。

答案 1 :(得分:0)

我在您的代码中看到两个错误:

  1. 您的函数是递归的,因此您需要将关键字rec添加到您的函数中,如let rec minList x
  2. 您的函数应该具有'a list -> 'a类型,但因为在第一个模式匹配中您返回一个列表,您将收到此错误。因为您正在使用'a list',所以保留列表的第一个元素可能会很好,然后如果最后,列表为空则返回第一个元素(这是列表的最小值)。