F#返回输入的大小,定义为构造函数的数量

时间:2016-09-29 00:00:04

标签: f#

初学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

1 个答案:

答案 0 :(得分:2)

我总结了您在评论中给出的提示,以便其他发现此问题的人可以看到答案得到解答,并且您能够解决问题:

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

  3. 在编写像size这样的递归函数时,有时会卡在"好吧,我需要在这里调用size函数...但是因为我没有&# 39;但是,我怎么知道它会回归什么?"摆脱困境的最好方法是假装你已经编写了已经的功能,所以你已经知道它将返回什么 - 然后使用该功能。奇迹般地,一切都成功了:当你完成这个功能时,它所调用的功能(本身)也已完成!有趣的是如何工作。 : - )

  4. 有一次你有一个看起来像这样的功能:

    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。那会永远终止吗?这些电话会不会做任何与以前的电话不同的事情,或者他们会继续循环播放"永远"直到函数堆空间不足?

  5. 最后,在您有两个或三个expr变量的情况下,您需要处理所有这些变量,而不仅仅是一个。

相关问题