I'm looking at the List documentation. It seems the library does not provide a sublist
function.
I'm trying to get list of elements from i to j. Now I have to write it as:
let rec sublist list i j =
if i > j then
[]
else
(List.nth list i) :: (sublist list (i+1) j)
which is quite concise but I'm questioning the efficiency of List.nth
, because if it's O(n), I would rather have to write it in a less concise way.
I'm wondering why didn't they provide List.sublist
func, if List.nth
is not O(1), because it's such a quite common operation..
Just have a function that takes the original list and a empty list. Build up the empty list(with the first half of the original list) until you reach the halfway point and then use the remainder of the original list and the built up empty list to generate your pairs.
Hence, to truncate a list, you need to create a new list that contains only the first elements (this is the only way to get the desired truncated list). let truncate : 'a -> 'a list -> 'a list = fun elt queue -> ...
So fold_left is "folding in" elements of the list from the left to the right, combining each new element using the operator.
While the answer provided by Pascal implements a nice candidate for List.sublist
the right answer is that you should probably better use an array of a list. The Array modules implements the Array.sub
function that you might use.
While in many imperatives languages such as C++ or Perl there is essentially no difference between lists and arrays, this is not the same in OCaml where:
Lists are better suited for recursive treatments and sequential access, i.e. is usually a better candidate as an array as argument to a recursive function, and you usually want to take a look at all the elements of the list.
Arrays are better suited for random access, structure alteration (such as sorting), or for numerical computations.
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]
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
.
I'm not very happy to let b
go negative but the version where it doesn't is more complicated.
One reference among quite a few for deforestation if you're interested: http://homepages.inf.ed.ac.uk/wadler/topics/deforestation.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With