我必须在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.
有人可以告诉我为什么吗?
答案 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是表达式的构造函数而不是类型。