如果在lambda Scheme中声明

时间:2015-03-01 18:53:52

标签: if-statement lambda scheme

我是一个新的阴谋家。我只是想问一下我是否可以在lambda中包含if语句?例如,(lambda(x)(如果e1 e2 e3))。我不明白为什么不这样做,但如果我这样写,我的程序就会失败。

非常感谢!

这是我的代码。我正在尝试使用高阶函数实现过滤器作为练习。既然@ sepp2k已经回答说在lambda中包含ifs是完全没问题的,我猜这是我使用foldr的问题吗?

如果有人能够对此有所了解,以帮助我了解它的运作方式,我真的很感激!

(define filter (f xs)
  (if (null? xs) '()
     (foldr (lambda (elem ys) ((if (f elem) (cons elem ys)
                                   (cons '() ys)))) '() xs)))

3 个答案:

答案 0 :(得分:2)

当然,我们可以在if内使用lambda,事实上,任何有效的表达式都可以在lambda内。您的代码中存在更严重的错误:

  1. 最内层的if表达式周围有其他(和不必要的)括号。 Scheme会将它们解释为一个功能应用程序,而这不是你想要做的事情
  2. else表达式的if错误,您只需不经过修改即可通过累加器
  3. 功能定义不正确
  4. 此外,整个功能可以简化,不需要最外面的if,并且可以改进缩进。试试这个:

    (define (filter f xs)
      (foldr (lambda (elem ys)
               (if (f elem)       ; if the predicate is true
                   (cons elem ys) ; then `cons` element to accumulator
                   ys))           ; otherwise leave accumulator alone
             '()
             xs))
    

    按预期工作:

    (filter even? '(1 2 3 4 5 6))
    => '(2 4 6)
    

答案 1 :(得分:1)

是的,在lambdas中使用ifs是完全有效的。如果你的程序失败,那必须是因为其他原因。

答案 2 :(得分:0)

围绕if电话的额外事件。 Scheme重载分组(list of expressions)和函数调用(+ 2 2)。 FWIW,您也可以使用foldl,因为foldr会占用O(|elements of the input|)个内存。

更深入,lambdas被称为"特殊形式"在计划中。这意味着他们遵守不同的评估规则。我只是提出这个问题,因为它提供了对方案的一个关键特征的一些见解:一切都只是一种形式。 define?特殊形式。 lambda?特殊形式。如果你真的有这种感觉,那么你无法自言自语。这意味着有很多特殊形式,即使它们看似自动化/烘焙,它们也不会有任何神秘的警告。

此外,仅供将来参考,以下是您的策划的几个宝石:MIT Scheme Reference (lambdas)Racket Guide (Pairs and Lists)