初学f#程序员在这里。
所以基本上我完全迷失了。我过去一小时一直在盯着这个问题,甚至不知道如何设置let参数的第一行。这个问题要求使用模式匹配定义一个递归函数大小:expr - > int,返回其输入表达式的大小,表达式为
中类型为expr的构造函数的数量这是递归函数:
size : expr -> int
以下是构造函数:
type oper = Neg | Not | Add | Mul | Sub | Less | Eq | And
type expr =
| C of int
| Op1 of oper * expr
| Op2 of oper * expr * expr
| If of expr * expr * expr
例如,
size(C 4)
会返回1
和
size (IF (C 4, Op2 (Add, C 1, C 2), C ())
将返回6
建议后更新:正在进行中!!
let rec size (e : expr) : int =
match e with
| C i -> 1
| Op1 (o, e1) -> size e1 + 1
| Op2 (o, e1, e2)-> size e2 + 1
| If (e1, e2, e3) -> size e3 + 1
答案 0 :(得分:2)
我总结了您在评论中给出的提示,以便其他发现此问题的人可以看到答案得到解答,并且您能够解决问题:
oper
类型的参数;一个expr
类型的参数就足够了。你不需要一个可变的计数器变量;递归会更好地为你服务。
在编写像size
这样的递归函数时,有时会卡在"好吧,我需要在这里调用size
函数...但是因为我没有&# 39;但是,我怎么知道它会回归什么?"摆脱困境的最好方法是假装你已经编写了已经的功能,所以你已经知道它将返回什么 - 然后使用该功能。奇迹般地,一切都成功了:当你完成这个功能时,它所调用的功能(本身)也已完成!有趣的是如何工作。 : - )
有一次你有一个看起来像这样的功能:
let rec size (e : expr) : int =
match e with
| C i -> 1
| Op1 (o, e1) -> size e + 1
// Rest of function omitted
那给你一个StackOverflowException,因为在size e
匹配案例中调用Op1
是一个无限递归循环。提示:在心理上追踪,并考虑它将经历的步骤。它会针对e
检查Op1
,并第二次致电size e
。该通话会针对e
检查Op1
,并第三次致电size e
。那会永远终止吗?这些电话会不会做任何与以前的电话不同的事情,或者他们会继续循环播放"永远"直到函数堆空间不足?
最后,在您有两个或三个expr
变量的情况下,您需要处理所有这些变量,而不仅仅是一个。