且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何从ocaml中的列表中获取子列表

更新时间:2023-12-04 21:11:40

let rec sublist b e l = 
  match l with
    [] -> failwith "sublist"
  | h :: t -> 
     let tail = if e=0 then [] else sublist (b-1) (e-1) t in
     if b>0 then tail else h :: tail
;;

sublist 3 5 [1;2;3;4;5;6;7;8;9] ;;
- : int list = [4; 5; 6]

以上内容或多或少是newacct解决方案的森林版本. newacct的解决方案分配了一个中间列表(drop i list),编译器可以在Haskell中进行优化,而在ML中则更为困难.因此,对于Haskell函数来说,他的版本是完美的,而对于ML语言来说,他的版本是次优的.两者之间的差异只是一个常数:两者均为O(e). zrr的版本为O(length(l)),因为List.filteri不知道f只会在一段时间后返回false,它会调用l中的所有元素.

The above is more or less a deforested version of newacct's solution. newacct's solution allocates an intermediate list (drop i list), which is possible for the compiler to optimize away in Haskell but much harder in ML. Therefore his version is perfectly fine for a Haskell function and marginally sub-optimal for an ML one. The difference between the two is only a constant factor: both are O(e). zrr's version is O(length(l)) since List.filteri doesn't know that f only returns false after a while, it calls it for all elements in l.

我不太愿意让b变为负数,但没有的版本则更加复杂.

I'm not very happy to let b go negative but the version where it doesn't is more complicated.

如果您有兴趣的话,您可以在很多参考资料中提及: http://homepages.inf.ed.ac.uk/wadler/topics/deforestation.html

One reference among quite a few for deforestation if you're interested: http://homepages.inf.ed.ac.uk/wadler/topics/deforestation.html