-2

This is my idea of the question but I can't correctly type fold_left method.

Example:

nonDecreasing[1;4;3;2;5;6] == [[1;4];[3];[2;5;6]] 
let nonDecreasing list = 
    match list with
    | [] -> help(a, b, c) = b
    | h::[] -> 2 (*I don't know, "2" is only to compile*)
    | h::t -> let help = List.fold_left (fun(prev, lFinal, lTemp) h -> if(h<List.hd(t)) then (List.hd(t), lFinal, h::lTemp) else (List.hd(t), lTemp@lFinal, h::lTemp)) (h, [], []) list ;;

I can't make it properly. I don't know what I do wrong with fold-left function.
aagi
  • 19
  • 3
  • 6
    Could you explain what your code is doing, what specific problem you're struggling with and preferably also format your code so it's all visible on one screen. You're more likely to get a good answer if you make it easy for us to understand what you're actually asking. – glennsl Nov 21 '18 at 18:33

1 Answers1

0

To build a list using fold it is probably easier to use fold_right, because you can only prepend elements to a list efficiently, and thus you should start building the list from the right, which is what fold_right does. (You can also use fold_left but then you need to reverse the list in an additional step or use the expensive list concatenation.)

A more simple example for building a list with fold_right would be to build a list of sums of elements of a list starting at the end of the list, e.g., sums [a; b; c] gives [a+b+c; b+c; c]. The code looks as follows.

let sums = List.fold_right
  (fun x ys ->
    match ys with
      | [] -> [x]
      | hd :: tl -> (x + hd) :: ys)
  [1; 2; 3; 4; 5]
  []

What the inner function does is to take the first element of the already built list and add it to the current element. (Keep in mind that the elements are visited from right to left.) Then the sum is added to the front of the already existing list.

Defining the non_decresing function works in a similar way. We have to work, however, with nested lists, which makes things a bit more complicated. The code is as follows.

let non_decreasing xs =
  List.fold_right
    (fun x outer ->
      match outer with
      | [] -> [[x]]
      | outer_hd :: outer_tl ->
          if x <= List.hd outer_hd then
            (x :: outer_hd) :: outer_tl
          else
            [x] :: outer)
    xs
    []

Again, we are building the list from right to left, but this time we have to decide to which of the two lists, we add the new element. Either we add it to the head of the outer list or we add a new list, containing just the current element, to the beginning of the outer list.

H. Rittich
  • 814
  • 7
  • 15