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 
+1

删除约0应该是你想要什么 –

+1

功能类型是位'EXPR - > int',这意味着它应该采取一个* *参数类型的'expr',并返回一个' int'。到目前为止,您已经定义了一个函数,它需要*两个*参数,一个'expr'和一个'oper'。你实际上并不需要第二个参数。 'expr'类型携带运算符作为数据;如果你有'expr',你可以通过使用匹配模式来获取其中的任何'操作符'值。即'用this匹配此表达式Op1(o,e) - > ...'现在你有一个变量'o',它是'thisExpr'中的'oper'。 – rmunn

+1

一旦你开始写你的功能,还有一个提示。当编写像'size'这样的递归函数时,有时候可能会卡住“好吧,我需要在这里调用我的'size'函数...但是由于我还没有写出它,我怎么知道它将会怎样返回?”最好的解决方法是**假装你已经编写了函数**,所以你已经知道它将返回什么 - 然后使用该函数。也就是说,如果你有一个'Op1',你知道它的大小是它所包含的'expr'的大小,再加上1.你可以告诉它它的大小吗?您正在编写的'size'函数! – rmunn

我来总结一下,你是在评论中给出的提示,让别人谁发现这个问题可以看出,这是回答你能解决这个问题:

  1. 您的原始代码不需要oper类型的参数; expr类型的单个参数就足够了。
  2. 你不需要一个可变的计数器变量;递归将更好地为您服务。

  3. 当写像size一个递归函数,有时你可以停留在“好了,我要在这里叫我size功能......但因为我没有写它,我怎么知道是什么回事回来?”最好的办法是假装你已经编写了功能已经,所以你已经知道它会返回什么 - 然后使用该功能。神奇的是,这一切都奏效了:当你完成这个功能时,它所调用的函数(本身)也完成了!有趣的是如何解决。 :-)

  4. 在一个点上,你有一个看起来像这样的功能:这是给你一个*Exception

    let rec size (e : expr) : int = 
        match e with 
        | C i -> 1 
        | Op1 (o, e1) -> size e + 1 
        // Rest of function omitted 
    

    ,因为调用size eOp1比赛机箱内部是一个无限递归循环。提示:在心理上追踪那个呼唤,并思考它会经历的步骤。它将检查eOp1,并且第二次致电size e。该电话将检查eOp1,并且第三次致电size e。那会终止吗?这些调用每个都会做与以前的调用不同的任何事情吗?或者他们会一直“循环”循环,直到函数堆栈空间不足?

  5. 最后,如果您有两个或三个expr变量,您需要处理所有这些变量,而不仅仅是一个。