2

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

我有

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 类型”。

问题是什么?我应该如何解决它?

4

2 回答 2

3

正如编译器所说,+运算符适用于整数。但是您将其应用于 type 的子表达式t。由于您的类型t可以表示诸如 之类的东西Plus(True, False),因此您需要决定您实际上想要如何处理这些情况。

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

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

于 2013-10-06T07:15:45.303 回答
1

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

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

并且您有一个类型问题:您的step函数int在执行时给出 a 并且在执行时t1+t2给出 a ;这是不可能的,函数应该返回一些已知的(单一)类型。boolt1>t2

您可能想要定义

  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
于 2013-10-06T07:02:06.893 回答