2015-11-06 113 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]