嵌套的Scheme函数没有正确返回

时间:2014-10-11 05:58:56

标签: scheme

我创建了一个函数,可以确定某个字符是否在列表中。虽然它本身工作正常,但是当被另一个函数调用时它无法正常工作,这个函数假设将列表的元素与几个关键字进行比较。我也尝试过使用memq,memv和member这两个函数,但它们也失败了。我想知道是什么导致我的程序没有返回#t和我出错的地方。

(define in?
  (lambda (y xs)
    (if (memq y xs) #t #f)))

(define det?
  (lambda (xs)
    (if (in? 'a xs) #t)
    (if (in? 'an xs) #t)
    (if (in? 'the xs) #t #f)))

2 个答案:

答案 0 :(得分:4)

作为Scheme中的显式返回语句,(* 1)没有这样的东西;一个过程只返回最后一个表达式的值。 Chris向您展示了cond和正确的双臂if的替代方案。

如果您发现自己的条件有#t#f,那么通常使用布尔逻辑会更优雅,在这种情况下:

(define det?
  (lambda (xs)
    (or (in? 'a xs) 
        (in? 'an xs) 
        (in? 'the xs))))

in?可以表示为

(define in? 
  (lambda (y xs)
    (and (memq y xs) #t)))

(* 1)当然,我在撒谎。你可以使用call/cc或其任何变体。它是一个先进的主题,不适合你的情境,但是让你一瞥它想要的东西:

(define det?
  (lambda (xs)
    (call/cc 
      (lambda (return)
        (when (in? 'a xs)   (return #t))
        (when (in? 'an xs)  (return #t))
        (when (in? 'the xs) (return #t))
        #f))))

请注意,我使用的是when,而不是if,因为它们仍处于单臂状态。

答案 1 :(得分:2)

您对if的使用不正确;只有最后if实际做了什么。 (为了帮助防止出现这些错误,Racket禁止使用单臂if表达式。)或许您想使用cond代替?

(define (det? xs)
  (cond ((in? 'a xs) #t)
        ((in? 'an xs) #t)
        ((in? 'the xs) #t)
        (else #f)))

此宏扩展为以下if s:

(if (in? 'a xs)
    #t
    (if (in? 'an xs)
        #t
        (if (in? 'the xs)
            #t
            #f)))

请注意这与您的一系列if表达式有何不同。