Ecila
Ecila

Reputation: 57

OCaml pattern matches values of type exp, but should match values of type 'a list

i have to do a program in ocaml that a Node with a string and a int is my first program in ocaml and in the web there isn't a lot of information

type tree = string*exp*tree*tree ;;
type exp = Etree of tree |  Int of int ;;

let eval (e:exp) = 
  match e with
    | []->[]
    | Int _ -> e
    | Etree(n) -> match n with
      | Node(s, i, t1, t2) -> eval i
;;

let t : Etree = Node("a", Int 1, Empty, Empty)

eval t;;

the IDE tell me that:

Type exp defined.
Toplevel input:
    | Int _ -> e
      ^^^^^
This pattern matches values of type exp,
but should match values of type 'a list.

Toplevel input:
let t : Etree = Node("a", Int 1, Empty, Empty)
        ^
Syntax error.

can someone tell me why?

Upvotes: -1

Views: 3176

Answers (2)

Rincewind
Rincewind

Reputation: 317

It looks to me like there are several issues with your types.

The error message you receive is because you try to match e, which has type exp, to the pattern []. But [] is an empty list and not a constructor of exp. If you want to have emptry expressions you need to provide a seperate constructor for that. For example

type exp = Etree of tree |  Int of int | Nothing;;

Additionally you later seem to want to provide an Empty tree to the tree t. I would expect you to get another error there because again Empty is not a value of type tree. Lastly I think you want to give the term t the type exp and not Etree beause Etree is a constructor for expressions and not a type.

Upvotes: 2

PatJ
PatJ

Reputation: 6144

The line | []->[] in your pattern matching makes the compiler believe that e is a list. You should remove that line (why do you have it in the first place?).

This won't be enough to correct the problem, as you use that Node constructor that you didn't declare. You should change your declaration of tree.

Now one other problem is that tree references exp even though exp hasn't been declared yet. That's problematic.

So, you should change your initial types declaration to:

type tree = Node of string * exp * tree * tree
and exp = Etree of tree |  Int of int ;;

Note the use of the and keyword before exp. That tells the compiler that the two type definitions are mutually recursive (that is, they mention each other).

Your second problem comes from the fact that types and constructors are two different things.

  • Types are an annotation on value, they are lowercase and on the left of the = in type declarations.
  • Constructors are values, they are Uppercase and on the right of the = in type declarations.

exp is a type, Etree is one of its constructor.

So your declaration of the value t should be

let t : exp = Etree( Node("a", Int 1, Empty, Empty) )

At this point, the compiler will complain about Empty (and rightfully so) because Empty is not part of your tree definition. Just the constructor to tree and you should be fine.

Upvotes: 4

Related Questions