F#返回大小的输入定义为构造函数
问题描述:
beginner f#程序员在这里。F#返回大小的输入定义为构造函数
所以基本上我完全失去了。在过去的一个小时里,我一直盯着这个问题,甚至不知道如何设置let参数的第一行。这个问题是要求使用模式匹配定义递归函数尺寸:EXPR - > int值返回其输入表达式的denfied从类型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
答
我来总结一下,你是在评论中给出的提示,让别人谁发现这个问题可以看出,这是回答你能解决这个问题:
- 您的原始代码不需要
oper
类型的参数;expr
类型的单个参数就足够了。 你不需要一个可变的计数器变量;递归将更好地为您服务。
当写像
size
一个递归函数,有时你可以停留在“好了,我要在这里叫我size
功能......但因为我没有写它,我怎么知道是什么回事回来?”最好的办法是假装你已经编写了功能已经,所以你已经知道它会返回什么 - 然后使用该功能。神奇的是,这一切都奏效了:当你完成这个功能时,它所调用的函数(本身)也完成了!有趣的是如何解决。 :-)-
在一个点上,你有一个看起来像这样的功能:这是给你一个*Exception
let rec size (e : expr) : int = match e with | C i -> 1 | Op1 (o, e1) -> size e + 1 // Rest of function omitted
,因为调用
size e
的Op1
比赛机箱内部是一个无限递归循环。提示:在心理上追踪那个呼唤,并思考它会经历的步骤。它将检查e
与Op1
,并且第二次致电size e
。该电话将检查e
对Op1
,并且第三次致电size e
。那会终止吗?这些调用每个都会做与以前的调用不同的任何事情吗?或者他们会一直“循环”循环,直到函数堆栈空间不足? 最后,如果您有两个或三个
expr
变量,您需要处理所有这些变量,而不仅仅是一个。
删除约0应该是你想要什么 –
功能类型是位'EXPR - > int',这意味着它应该采取一个* *参数类型的'expr',并返回一个' int'。到目前为止,您已经定义了一个函数,它需要*两个*参数,一个'expr'和一个'oper'。你实际上并不需要第二个参数。 'expr'类型携带运算符作为数据;如果你有'expr',你可以通过使用匹配模式来获取其中的任何'操作符'值。即'用this匹配此表达式Op1(o,e) - > ...'现在你有一个变量'o',它是'thisExpr'中的'oper'。 – rmunn
一旦你开始写你的功能,还有一个提示。当编写像'size'这样的递归函数时,有时候可能会卡住“好吧,我需要在这里调用我的'size'函数...但是由于我还没有写出它,我怎么知道它将会怎样返回?”最好的解决方法是**假装你已经编写了函数**,所以你已经知道它将返回什么 - 然后使用该函数。也就是说,如果你有一个'Op1',你知道它的大小是它所包含的'expr'的大小,再加上1.你可以告诉它它的大小吗?您正在编写的'size'函数! – rmunn