2015-11-06 109 views
0
(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代码,我到目前为止有以下内容:将计划转换为OCaml? ('列表vs'列表清单 - >'列表清单)

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类型的表达式。

我是一个初学者到功能性的语言和任何帮助将不胜赞赏。

回答

0

我看到你的代码中有两处错误:

  1. 你的函数是递归的,所以你需要将关键词rec添加到您的功能,这样let rec minList x
  2. 你的功能应该有类型'a list -> 'a但由于在第一模式匹配你正在返回一个列表,你会得到这个错误。因为你正在使用'a list',所以也许最好保留列表的第一个元素,然后如果最后列表为空,那么返回第一个元素(它是列表的最小值)。
1

这是与类型系统的区别。

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

> (min `(1 2 3)) 
1 

> (min `()) 
() 

用OCaml你不能,输出必须是相同的类型。您可以在Real World Ocaml中阅读更多关于类型推断的内容。

你不想从空列表中返回一个int,你想失败。

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

而BTW,| hd::tl when tl = [] -> hd的情况可以简化为| [x] -> x。 至于tl = [],hd::tl = hd::[] = [hd]