2010-11-11 66 views
1

在Ruby中,你可以像这样创建一个简单的切换功能:是否可以在方案中制作切换功能?

@switch = false 

def toggle 
    @switch = [email protected] 
end 

toggle # => true 
toggle # => false 
toggle # => true 

我想知道是否有可能做到这一点的方案。我能得到的最接近的是:

(define a #f) 
(define (toggle a) 
    (cond ((eq? a #t) #f) 
     (else #t))) 

(define a (toggle a)) 
a # => #t 
(define a (toggle a)) 
a # => #f 
(define a (toggle a)) 
a # => #t 

谢谢。

(define switch #f) 
(define (toggle) 
    (set! switch (not switch)) 
    switch) 

这是功课:

+0

“无突变”的概念是功能不应该修改自身以外的某些东西。这样,您就可以运行函数而不用担心它们是否会对程序的其余部分产生奇怪的影响。 – erjiang 2010-11-11 16:01:32

+0

我了解功能范式(尽管我不确定我是否愿意订阅它)。“从不”非常严格。有时候,你不要暗暗的想,“哦,记住事件的发生会非常好。”任何交互式软件都必须跟踪交互 - 必须记住一些事件/设置。 – Tim 2010-11-12 00:06:56

回答

0

我会写这样的事:

(define switch 
    ((lambda (state) 
    (lambda() 
     (begin 
     (set! state (not state)) 
     state))) 
    #f)) 

可以调用这样的:

> (switch) 
#t 
> (switch) 
#f 
> (switch) 
#t 

一点解释:外的λ是一个函数,它的初始状态,并返回另一个函数在每次调用时都会前后翻转该状态。请注意,在最后一行上,#f立即调用外部函数;开关然后被定义为这个调用的结果,内部函数在关闭中捕获state

你也可以写这样的事:

(define make-switch 
    (lambda() 
    ((lambda (state) 
     (lambda() 
     (begin 
      (set! state (not state)) 
      state))) 
    #f))) 

make-switch需要什么我们以前并把它封装在另一个功能。现在我们有一个制造开关的工厂,每个开关都有自己的内部状态。因此,我们可以写这样的事:

(define switch-a (make-switch)) 
(define switch-b (make-switch)) 

而且看到每个开关独立于其他的:

> (switch-a) 
#t 
> (switch-b) 
#t 
> (switch-b) 
#f 
> (switch-a) 
#f 

同样,你可以参数化make-switch来设置交换机的初始状态,并上。

希望这会有所帮助。

+0

我很敬畏。你是一位拉姆达拉索尔大师。这给了我很多咀嚼。谢谢。 – Tim 2010-11-13 03:52:15

+0

@Tim像所有的事情一样,只需要一点练习。继续堵塞,你会得到它。 (为了记录,我发现第二次通过The Little Schemer的工作非常有帮助。)并且记住:如果有疑问,只需在它周围包裹另一个'lambda'。 :) – 2010-11-14 19:05:28

3

,如果你喜欢,你可以做同样的方式?

+0

不是功课。我喜欢比较和对比的语言,我的砧板上的语言是计划。我不知道这个开关!功能 - 从来没有出现在小Schemer。感谢您的回答。 – Tim 2010-11-11 05:20:54

+1

我认为你的意思是* set!*函数,但是对于Scheme程序员来说,他们试图避免突变,这可能就是为什么它不会出现在The Little Schemer中。计划是非常光滑的 - 希望你会在一段时间内保持在你的区块。 – xscott 2010-11-11 05:35:32

+0

是的,你是对的。我的意思是设置!现在,使用方案有点像运行时间间隔。这是一个令人不舒服的挑战,但我也可以告诉我们,在这种新的(对我来说)功能性方式中思考事物是否有好处。 – Tim 2010-11-11 23:56:59