我如何调用一个在球拍中进行参数的函数?

时间:2013-12-15 11:32:16

标签: math functional-programming scheme computer-science racket

我仍然是球拍语言的新手。 我正在用球拍实现一个开关盒,但它不起作用。 所以,我转向使用等于和条件。我想知道如何调用一个输入的函数。例如:factorial(n)函数 我想把它叫做:

(if (= c 1) (factorial (n))

3 个答案:

答案 0 :(得分:2)

此代码段存在两个语法问题:

(if (= c 1) (factorial (n)))

对于初学者来说,Racket中的if表达式需要三个部分:

(if <condition> <consequent> <alternative>)

要解决的第一件事是提供一个表达式,该表达式将在c等于1时执行,而另一个表达式将在c不等于1时运行}。说,像这样:

(if (= c 1) 1 (factorial (n)))

现在第二个问题:在Scheme中,当用括号括起符号时,意味着你正在尝试执行一个函数。因此,如果您编写(n),解释器会认为n是一个没有参数的函数,并且您正在尝试调用它。要解决此问题,只需删除()周围的n

(if (= c 1) 1 (factorial n))

现在语法问题已经解决了,让我们检查逻辑。在Scheme中,我们通常使用递归来表达解决方案,但递归必须在某个时刻前进,因此它最终会结束。如果你继续将相同的参数传递给递归,而不修改它,你将陷入无限循环。以下是编写递归factorial过程的正确方法:

(define (factorial n)
  (if (<= n 0)                    ; base case: if n <= 0
      1                           ; then return 1
      (* n (factorial (- n 1))))) ; otherwise multiply and advance recursion

注意我们如何在每一步递减n,以确保它最终会达到零,从而结束递归。一旦您对此解决方案感到满意,我们就可以考虑让它变得更好。阅读tail recursion,看看编译器如何优化我们的循环,只要我们以这样的方式编写它们,即在每个执行路径上完成的最后一件事就是递归调用,之后没有什么可做的。例如,可以如下更有效地编写前面的代码,并查看我们如何在参数中传递累积的答案:

(define (factorial n)
  (let loop ([n n] [acc 1])
    (if (<= n 0)
        acc
        (loop (- n 1) (* n acc)))))

<强>更新

在看了评论之后,我发现你想要实现一个switchcase程序。再一次,你宣布功能的方式存在问题。这是错的:

(define fact(x)

正确的方法是:

(define (fact x)

对于实际实现switchcase,可以在尝试时使用嵌套的if,但这不是最好的方法。了解如何使用cond表达式或case表达式,任何一个都可以使您的解决方案更简单。无论如何,如果c既不是1也不是2,您必须提供其他条件。此外,您对参数名称感到困惑 - 是c还是x?有了所有建议,以下是代码的外观:

(define (switchcase c)
  (cond ((= c 1) (fact c))
        ((= c 2) (triple c))
        (else (error "unknown value" c))))

答案 1 :(得分:0)

在racket-lang中,if的条件语法具有语法:

(if <expr> <expr> <expr>)

因此,在您的情况下,您必须提供另一个<expr>

(define (factorial n)
  (if (= n 1)     1     (* n (factorial (- n 1)))))
      ;^exp       ^exp  ^exp        
(factorial 3)

结果将是6

<强>更新

(define (factorial n)
  (if (= n 1) 1 (* n (factorial (- n 1)))))

(define (triple x)
  (* 3 x))

(define (switchcase c)
  (if (= c 1) 
    (factorial c)
    (if(= c 2)
      (triple c) "c is not 1 or 2")))

(switchcase 2)

答案 2 :(得分:0)

如果你想要更接近开关盒的东西,你可以返回程序。

(define (switch input cases)
 (let ((lookup (assoc input cases)))
    (if lookup
        (cdr lookup)
        (error "Undefined case on " input " in " cases))))

(define (this-switch c)
 (let ((cases (list (cons 1 triple)
                    (cons 2 factorial))))
   ((switch c cases) c)))