OCaml模式匹配exp类型的值,但应匹配类型'a list

时间:2018-01-12 17:49:08

标签: ocaml

我必须在ocaml中执行一个带有字符串和int的节点 是我在ocaml和网络上的第一个程序,没有太多的信息

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;;
IDE告诉我:

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.

有人可以告诉我为什么吗?

2 个答案:

答案 0 :(得分:4)

模式匹配中的行| []->[]使编译器认为e是一个列表。你应该删除那一行(为什么你首先拥有它?)。

这不足以解决问题,因为您使用了未声明的Node构造函数。你应该改变树的声明。

现在另一个问题是tree引用exp,即使尚未声明exp。这有问题。

因此,您应该将初始类型声明更改为:

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

请注意在and之前使用exp关键字。这告诉编译器两个类型定义是相互递归的(也就是说,它们互相提及)。

你的第二个问题来自于类型和构造函数是两个不同的东西。

  • 类型是值的注释,它们是小写的,在=类型声明的左侧。
  • 构造函数是值,它们是大写的,在=类型声明的右侧。

exp是一种类型,Etree是其构造函数之一。

因此,您对值t的声明应为

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

此时,编译器会抱怨Empty(并且理所当然),因为Empty不是tree定义的一部分。只是tree的构造函数,你应该没问题。

答案 1 :(得分:2)

在我看来,您的类型存在一些问题。

您收到的错误消息是因为您尝试将类型为exp的e与模式[]匹配。但是[]是一个空列表而不是exp的构造函数。如果你想拥有emptry表达式,你需要为它提供一个单独的构造函数。例如

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

此外,您后来似乎想要向树t提供一个空树。我希望你在那里得到另一个错误,因为再次Empty不是类型树的值。最后,我认为你想给术语t类型exp而不是Etree因为Etree是表达式的构造函数而不是类型。