OCaml:使用匹配和类型转换

OCaml:使用匹配和类型转换,ocaml,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

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

我有

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”


有什么问题?我应该如何修复它?

匹配表达式(不幸的是)没有结束标记。对于嵌套的
匹配
必须使用括号或
开始
<代码>结束例如代码

match x with
  SomePattern y -> begin
    match y with
       AnyotherThing -> ....
       YetAnotherPattern z -> ....
  end
您有一个类型问题:您的
步骤
函数在执行
t1+t2
时给出了
int
,在执行
t1>t2
时给出了
bool
;这是不可能的,函数应该返回一些已知(单一)类型

您可能需要定义

  type result_t = NoResult | IntResult of int | BoolResult of bool
并给出
IntResult(t1+t2)
BoolResult(t1>t2)

或者您可以简单地让
step
返回一些
t
值,即
True
False
Int(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

match
表达式(很遗憾)没有结束标记。对于嵌套的
匹配
必须使用括号或
开始
<代码>结束例如代码

match x with
  SomePattern y -> begin
    match y with
       AnyotherThing -> ....
       YetAnotherPattern z -> ....
  end
您有一个类型问题:您的
步骤
函数在执行
t1+t2
时给出了
int
,在执行
t1>t2
时给出了
bool
;这是不可能的,函数应该返回一些已知(单一)类型

您可能需要定义

  type result_t = NoResult | IntResult of int | BoolResult of bool
并给出
IntResult(t1+t2)
BoolResult(t1>t2)

或者您可以简单地让
step
返回一些
t
值,即
True
False
Int(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

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

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


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

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

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

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