2013-04-20 52 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

相关问题