真/假评估在Scheme中无法正常工作

时间:2012-12-15 16:23:12

标签: string functional-programming scheme racket

我正在尝试比较两个布尔值:

(if (equal? #f (string->number "123b"))
      "not a number"
      "indeed a number")  

当我在 DrRacket 的命令行中运行时,我得到"not a number"但是,当我 把那段代码放在我的大代码中,该函数不会返回该字符串("not a number"),这里是代码:

(define (testing x y z)

    (define badInput "ERROR")  

    (if (equal? #f (string->number "123b"))
          "not a number"
          "indeed a number")  

    (display x))

从命令行:(testing "123" 1 2) 显示:123

为什么?

此外,无论何时我选择,我怎样才能返回一个值?

由于

4 个答案:

答案 0 :(得分:4)

试试这个:

(define (testing x)
  (if (equal? #f (string->number "123b"))
      (display "not a number")
      (display "indeed a number"))
  (display x))

您丢弃了if表达式的结果。条件工作正常,但没有对结果字符串做任何事情,它只是被忽略了。整个过程现在返回#<void>,因为display是一个副作用操作,没有自己的值。此外,我删除了badInput变量以及yz参数,因为它们根本没有被使用。

要从过程返回一个值,只需在过程的主体末尾添加要返回的值的表达式 - 这就解释了为什么代码无效,只有 last expression返回一个值,尽管你可以使用任何表达式(包括最后一个表达式)进行副作用操作(例如,调用display)。

事实上,您可以通过返回一个值来更加惯用地编写代码,注意if中的条件现在实际上取决于传递的x参数:

(define (testing x)
  (if (not (string->number x))
      (string-append "not a number " x)
      (string-append "indeed a number " x)))

(displayln (testing "123"))
=> indeed a number 123

(displayln (testing "123b"))
=> not a number 123b

修改

关于你问题的最后一次编辑,我相信你正在寻找这样的东西:

(define (convert originalNumber s_oldBase s_newBase)
  (if (or (not (string->number originalNumber)) ; validate error conditions first
          (not (string->number s_oldBase))
          (not (string->number s_newBase)))
      "ERROR"     ; if one of the input values is wrong, return an error message
      (begin      ; else
        <body>))) ; put the rest of the procedure's body in here

或者,如果您更喜欢使用cond

(define (convert originalNumber s_oldBase s_newBase)
  (cond ((or (not (string->number originalNumber)) ; validate error conditions
             (not (string->number s_oldBase))
             (not (string->number s_newBase)))
         "ERROR")  ; if one of the input values is wrong, return an error message
        (else      ; else
         <body>))) ; put the rest of the procedure's body in here

答案 1 :(得分:2)

这样做的原因是,即使您的条件是评估为假,您也只是放弃了该结果。

您输入的内容相当于:

(define (testing x y z)

    (define badInput "ERROR")  

    "not a number"

    (display x))

"not a number"刚被丢弃。

要返回它,请尝试类似

的内容
(define (testing x y z)

    (define badInput "ERROR")  
    (cond

        ((equal? #f (string->number "123b"))
              "not a number")  

        (else (display x))))

答案 2 :(得分:1)

函数的值是其正文中最后一个表达式的值。 testing函数正文中的最后一个表达式是(display x),因此这是您函数的值。由于您的if不是身体中的最后一个表达,并且没有任何副作用,因此它基本上什么都不做。

如果您在致电if后移动displaytesting将显示x,然后返回&#34;而不是数字&#34;。

答案 3 :(得分:1)

这在这里会有些过分,但您可以通过调用call/cc(或call-with-current-continuation)设置的续集来直接从任意位置返回值:

(define (primo args ...)
   (call/cc (lambda (k) (secundo k args ...))))

(define (secundo k args ... )
  ... do your stuff and whenever you feel like it,
  ... return a value by calling
  (k value)
  ....
  .... )