2010-11-11 64 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