OCaml样式,用于将两个排序列表合并为一个排序列表的函数

use*_*357 3 ocaml

我是OCaml的新手,我正在审核课程.我有一个作业提示,上面写着:"合并xs ys需要两个整数列表,每个列表按递增顺序排序,并按排序顺序返回单个合并列表."

我已经成功编写了一个有效的函数:

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]
;;
Run Code Online (Sandbox Code Playgroud)

我想知道我的代码是否被认为是可接受的OCaml风格?我想避免形成任何坏习惯.它感觉组成密集,但也许那是因为我还不习惯OCaml.

谢谢.

Jef*_*eld 5

我个人觉得很难遵循if hxs <= (match ...),很难很好地格式化.所以我可能会写

 ...
 let hys =
   match ys with
   | [] -> hxs
   | hys :: _ -> hys
 in
 if hxs < hys then
    hxs :: merge txs ys
 ...
Run Code Online (Sandbox Code Playgroud)

不过,我想可能是更好的匹配都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
Run Code Online (Sandbox Code Playgroud)

我认为这可以更好地捕捉问题的对称性.

我认为当代码的长度与它解决的问题的简单性很好地匹配时,这是很好的.合并很简单,所以代码不需要很长(在我看来).

  • 如果你想玩聪明,你也可以将前两个案例表述为单个`| ([],休息)| (休息,[]) - >休息. (2认同)