Reputation:
I'm a beginner and the terms I used may not be accurate.
I have
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
I want to implement a eval function.
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;;
Error occurs at Plus(t1, t2) -> t1+t2
, saying "This expression has type t but an expression was expected of type int".
What is the problem? How should I fix it?
Upvotes: 2
Views: 3184
Reputation: 1
The match
expression has (unfortunately) no end-markers. For nested match
you have to use parenthesis or begin
... end
e.g. code
match x with
SomePattern y -> begin
match y with
AnyotherThing -> ....
YetAnotherPattern z -> ....
end
and you have a type issue: your step
function is giving an int
when doing a t1+t2
and is giving a bool
when doing t1>t2
; this is not possible, a function should return some known (single) type.
You may want to define
type result_t = NoResult | IntResult of int | BoolResult of bool
and give IntResult (t1+t2)
or BoolResult (t1>t2)
or you could simply have step
return some t
value, i.e. True
, False
, Int (t1+t2)
I would code instead
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
Upvotes: 0
Reputation: 66823
As the compiler says the +
operator works on ints. But you're applying it to subexpressions of type t
. Since your type t
can represent things like Plus(True, False)
, you need to decide how you actually want to handle these cases.
You also need to decide on a return type. Some of your cases seem to be returning bool
, others return t
, and others return int
. From the look of things, you might want to return t
in all cases. If so, you would return Int n
instead of just plain n
.
(Basile Starynkevitch has written some code that tackles these problems. Maybe think about them first yourself then look at his code :-)
Upvotes: 2