2016-04-18 2 views
0

Я получаю ошибку совпадения для моего кода OCaml, и я понятия не имею, в чем проблема. Я попытался имея только один случай и происходит оттуда, чтобы выяснить, где проблема появляется, но ошибка я получаю это:Ошибка сбоя в матче OCaml

Exception: Match_failure ("hw2.ml", 49, 0). 

Код:

let rec compileStack(il : instr list) (st : float list) = 
match (il,st) with 
[],[_] -> List.hd st 
|((Push f)::t),[_] -> compileStack t (f::st) 
|(Swap)::t, h2::h1::st -> compileStack t (h2::h1::st) 
|(Calculate op)::t, h1::h2::st -> 
    match op with 
    Plus -> compileStack t (h2+.h1::st) 
    | Minus -> compileStack t (h2-.h1::st) 
    | Times -> compileStack t (h2*.h1::st) 
    | Divide -> compileStack t (h2/.h1::st) ;;        

let execute (li : instr list) : float = 
    let stack = [] in 
    compileStack li stack;; 

Любое предложение будет высоко оценен, застрял на это в течение 2 часов.

+1

где находится строка 49? –

+2

Каковы ваши исходные данные для неудачного теста? Кстати, сопоставление образцов на (il, st) не является исчерпывающим: вы пропустили кучу случаев. Кажется, это ваша проблема. –

ответ

2

При компиляции обратите внимание на выход компилятора. Если он говорит что-то вроде

Warning ...: this pattern-matching is not exhaustive. 

то это обычно означает, что вы пропустили некоторые случаи. Кстати, компилятор представляет пример пропущенных случаев.

Учитывая вашу проблему, я бы разделил разные задания на разные функции - это позволит вам справляться с этими случаями проще; также не забывайте о потоках стека, которые происходят, когда в стеке недостаточно данных для выполнения свопов или двоичных арифметических операций. См. Пример ниже.

(* just type aliases for convenience *) 
type stack = float list 
type binop = float -> float -> float 

(* helper function to prevent nested pattern matching below *) 
let denote_operation (op : oper) : binop = 
    match op with 
    | Plus -> (+.) 
    | Minus -> (-.) 
    | Times -> (*.) 
    | Divide -> (/.) 

(* This function executes only 1 instruction and 
    returns 'stack option', which may signal stack underflow *) 
let execute_instruction (i : instr) (st : stack) : stack option = 
    match i with 
    | Push f -> Some (f :: st) 
    | Swap -> 
     (match st with 
      | y :: x :: st' -> Some (x :: y :: st') 
      | _ -> None) 
    | Calculate op -> 
     (match st with 
      | y :: x :: st' -> Some ((denote_operation op x y) :: st') 
      | _ -> None) 

(* this function deals with a bunch of instructions *) 
let rec execute_program (il : instr list) (st : stack) : stack option = 
    match il with 
    | [] -> Some st 
    | i :: il' -> 
     match (execute_instruction i st) with 
     | None -> None 
     | Some st' -> execute_program il' st' 
Смежные вопросы