LINUX.ORG.RU

ocaml, туплю


0

0

нужна функция, которая получает непустой список и возвращает
максимальный элемент в списке и части списка слева и справа от макс. эл-та

let rec splitmax seq =
    match seq with
    | [] -> [], 1.0e10, []
    | t0::[] -> [], t0, []
    | t0::sub ->
        let left, t1, right = splitmax(sub) in
        if t1 > t0
            then (t0::left, t1, right) 
            else ([], t0, sub)
;;

такой вариант работатет; 
но если убрать первую строку в match with возникает Matching exception
не понимаю почему -- пустой список в качестве аргумента никогда не
передаётся.  в чём дело?

anonymous

let splitmax i =
  let rec sub l r max res=
    match r with
      | [] -> res
      | h::t ->
          if h > max then sub (h::l) t h (List.rev(h::l), t, h)
          else sub (h::l) t max res;
  in let h::t = i
  in sub [h] t h ([h], t, h);;

yuriy123
()
Ответ на: комментарий от yuriy123

действительно, хвостовая рекурсия это правильно.

но всё-таки хочется понять, почему в первом варианте возникает ошибка если не указать случай "|[]->".

anonymous
()

>пустой список в качестве аргумента никогда не
передаётся.  в чём дело?

ocaml этого не знает. список подстановок должен быть полным, учитывать все варианты. Попробуй использоват универсальный образец

 let rec sub = 
  fun list ->
    match list with
      | h :: [] -> [], h, []
      | h :: t -> ((fun (l, c, r) ->  if c > h then (h :: l, c, r) else ([], h , t)) (sub t) )
      | _ -> [], 1.0e10, [] ;;
       ^^^
        это он.

>возникает Matching exception

Странно, а у меня warning возникает, если я какой либо вариант не учту. В частнсти если затереть последнюю строчку.

# let rec sub = 
  fun list ->
    match list with
      | h :: [] -> [], h, []
      | h :: t -> ((fun (l, c, r) ->  if c > h then (h :: l, c, r) else ([], h , t)) (sub t) );;
        Characters 33-172:
Warning: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched:
[]
  ....match list with
        | h :: [] -> [], h, []
        | h :: t -> ((fun (l, c, r) ->  if c > h then (h :: l, c, r) else ([], h , t)) (sub t) )..
val sub : 'a list -> 'a list * 'a * 'a list = <fun>
# 

ugoday ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.