user746461
user746461

Reputation:

OCaml: use match and type casting

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

Answers (2)

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

Jeffrey Scofield
Jeffrey Scofield

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

Related Questions