匹配失败问题OCaml

时间:2016-04-18 08:03:50

标签: 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 个答案:

答案 0 :(得分: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'