变体,递归函数和类型推断

时间:2011-03-21 22:20:44

标签: recursion ocaml type-inference variant

我在OCaml非常新,但过去两天都在工作,以便更好地了解如何使用它。 我最近做了很多事情但有些事情让我无法前进。

我正在尝试在OCaml中实现evalexpr。很容易使用这个语言,你会说:所以我想,我做的第一个,使用常规的整数,工作得很好。 但是现在我正在尝试使用我的OWN类型和我自己的函数来解决操作:当然,这并不像我预期的那么容易。

type expr =
  | Number of MyInt.myint
  | Sum of (expr * expr)
  | Sub of (expr * expr)
  | Product of (expr * expr)
  | Divide of (expr * expr)
  | Modulo of (expr * expr)

let rec evalexpr expr = function
  | Number n       -> n
  | Sum (a, b)     -> MyInt.add (evalexpr a) (evalexpr b)
  | Sub (a, b)     -> MyInt.sub (evalexpr a) (evalexpr b)
  | Product (a, b) -> MyInt.mul (evalexpr a) (evalexpr b)
  | Divide (a, b)  -> MyInt.div (evalexpr a) (evalexpr b)
  | Modulo (a, b)  -> MyInt.modulo (evalexpr a) (evalexpr b)

这对我来说似乎不错......但是编译器不同意。 我认为很明显“(evalexpr a)”的类型是MyInt.myint,因为它是evalexpr函数可以返回的唯一最终返回值:仍然,编译器认为它的类型是“expr - > MyInt.myint ”

这是否意味着它不应用函数evalexpr并返回函数本身?如果是这样,为什么它会这样做呢? 我只是想不出来。而且我想不出另一种方法来做我想在这里实现的目标。

2 个答案:

答案 0 :(得分:7)

expr功能中删除evalexpr

let rec evalexpr = function
    ...

通过它在那里,你宣称该函数需要2个参数。第一个将绑定到变量expr,第二个将在函数体中匹配。然后,当您尝试以递归方式调用它时,使用单个参数调用evalexpr,从而产生期望第二个参数的函数。那么你的函数自然无法对函数进行操作,从而导致错误。

答案 1 :(得分:2)

好的,我认为它应该是这样的:

let rec evalexpr = function
  | Number n       -> n
  | Sum (a, b)     -> MyInt.add (evalexpr a) (evalexpr b)
  | Sub (a, b)     -> MyInt.sub (evalexpr a) (evalexpr b)
  | Product (a, b) -> MyInt.mul (evalexpr a) (evalexpr b)
  | Divide (a, b)  -> MyInt.div (evalexpr a) (evalexpr b)
  | Modulo (a, b)  -> MyInt.modulo (evalexpr a) (evalexpr b)

函数语句已经为你接受了一个参数,所以你实际声明的是一个函数,它接受一个参数并返回一个函数