2013-04-20 51 views
3

我是OCaml的新手,我正在審覈一個類。我有一個家庭作業提示,其內容如下: 「合併xs ys需要兩個整數列表,每個列表按升序排列, 並按排序順序返回單個合併列表。」OCaml樣式,用於將兩個排序列表合併到一個排序列表中的函數

我已經成功地寫了工作的功能:

let rec merge xs ys = match xs with 
    | [] -> ys 
    | hxs::txs -> if hxs <= (match ys with 
    | [] -> hxs 
    | hys::tys -> hys) 
     then hxs :: merge txs ys 
     else match ys with 
     | [] -> xs 
     | hys::tys -> hys :: merge xs tys in 
merge [-1;2;3;100] [-1;5;1001] 
;; 

我想知道,如果我的代碼被認爲是可接受的OCaml的風格?我想避免形成任何壞習慣。它感覺組成密集,但也許這是因爲我還不習慣OCaml。

謝謝。

回答

5

我個人覺得難以遵循if hxs <= (match ...),很難很好地格式化它。所以,我可能會寫

... 
let hys = 
    match ys with 
    | [] -> hxs 
    | hys :: _ -> hys 
in 
if hxs < hys then 
    hxs :: merge txs ys 
... 

不過,我想可能是更好的在同一時間既xsys匹配:

let rec merge xs ys = 
    match xs, ys with 
    | [], _ -> ys 
    | _, [] -> xs 
    | hx :: txs, hy :: tys -> 
     if hx < hy then hx :: merge txs ys else hy :: merge xs tys 

我認爲這抓住了問題的對稱性更好。

我認爲當代碼的長度與它解決的問題的簡單性相匹配時,它是好的。合併很簡單,所以代碼不需要很長(在我看來)。

+2

如果你想玩得很聰明,你還可以將前兩種情況作爲一個單獨的'| | ([],rest)| (休息,[]) - >休息。 – gasche 2013-04-20 07:05:25

+0

非常感謝你。我覺得必須有一種方法來重構我使用的所有比賽。這是一個很好的例子。 – user2301357 2013-04-24 20:45:04

相關問題