OCaml:使用匹配和类型转换

时间:2013-10-06 06:56:22

标签: ocaml

我是初学者,我使用的术语可能不准确。

我有

type t = True | False | If of t * t * t | Int of int | Plus of t * t | GT of t * t

let isval t =
  match t with
      True|False -> true
    | Int _ -> true
    | _ -> false

我想实现一个eval函数。

let rec step t =
   match isval t with
      true -> raise NormalForm
    | false -> match t with
          If(t1, t2, t3) when t1=True -> t2
        | If(t1, t2, t3) when t1=False -> t3
        | Plus(t1, t2) -> t1+t2
        | GT(t1, t2) ->  t1>t2
        | _ -> raise NormalForm;;

Plus(t1, t2) -> t1+t2发生错误,说“此表达式的类型为t,但表达式的类型为int”。

有什么问题?我该如何解决?

2 个答案:

答案 0 :(得分:3)

正如编译器所说+运算符在int上工作。但是你将它应用于t类型的子表达式。由于您的类型t可以代表Plus(True, False)之类的内容,因此您需要决定实际上如何处理这些案例。

您还需要决定返回类型。您的某些案例似乎正在返回bool,其他案件返回t,其他案件则返回int。从外观上看,您可能希望在所有情况下都返回t。如果是这样,您将返回Int n而不是仅仅n

(Basile Starynkevitch编写了一些解决这些问题的代码。也许先自己先考虑一下然后看看他的代码: - )

答案 1 :(得分:1)

match表达式(遗憾的是)没有结束标记。对于嵌套match,您必须使用括号或begin ... end,例如代码

match x with
  SomePattern y -> begin
    match y with
       AnyotherThing -> ....
       YetAnotherPattern z -> ....
  end

并且您遇到了类型问题:step函数在执行int时提供t1+t2,在执行bool时提供t1>t2;这是不可能的,函数应该返回一些已知的(单一)类型。

您可能想要定义

  type result_t = NoResult | IntResult of int | BoolResult of bool

并提供IntResult (t1+t2)BoolResult (t1>t2)

或者您可以让step返回一些t值,即TrueFalseInt (t1+t2)

我会改为编码

let asint = function Int x -> x | _ -> failwith "not an integer"

let rec eval = function
  True -> True
  | False -> False
  | Int x -> Int x
  |  If (cond,thenpart,elsepart) -> begin
       match eval cond with
         True -> eval thenpart
        | False -> eval elsepart
        | _ -> failwith "bad condition"
    end 
  | Plus (l, r) -> 
       Int (asint (eval l) + asint (eval r))
  | GT (l, r) -> begin
       if (asint (eval l)) > (asint (eval r)) then
         True
       else 
         False
    end