type t=Num of int (* need to change to Num2 of int *)
type e = Num of int
| Add of e*e
let rec intp e : t =
| Num n -> t (n)
| Add (e1, e2) -> int (intp e1) + int (intp e2)
我想添加两个变量,这是用户定义的类型,但他们不能添加用户定义的类型,所以我使用int()转换类型,但未绑定值int发生。如何将类型t转换为int?
您的示例代码没有两个Num
的定义。我假设第二个是你想要的。
通常提取值的方法是通过模式匹配。下面是一个函数,如果是Num
,则返回类型为e
的值内部的int,如果是Add
,则返回0:
let int_val x = match x with Num i -> i | Add _ -> 0
您可以在代码中以类似的方式使用模式匹配来从Num i
中提取int值。
如果您希望intp
返回类型t
,则必须使用其Num
构造函数。如果在用Num2
构造的e
值上运行intp
,则通过模式匹配提取其int值,并用Num
构造t
值。
知道intp
最终会返回一个t
的值,我们可以对每个Add
的子表达式递归调用intp
的结果使用模式匹配来提取两个int值,然后将它们加在一起,用Num
构造一个t
的值。
type t = Num of int
type e =
| Num2 of int
| Add of e * e
let rec intp = function
| Num2 n -> Num n
| Add (e1, e2) ->
let Num n1 = intp e1 in
let Num n2 = intp e2 in
Num (n1 + n2)
utop # intp @@ Add (Num2 9, Add (Num2 3, Num2 1));;
- : t = Num 13
进一步阅读
这不是尾部递归的缺点。但它本质上是一个二叉树,ivg写了一个很好的尾递归指南,其中包括树的尾递归。这是一段很长的旅程,但它可能会帮助您将这个函数提升到一个新的水平。