從某種意義上說,Haskell 是一種純粹的函式式語言,當然,慣用代碼試圖盡可能地具有函式式。同時,Haskell 確實提供了對一些其他語言熟悉的命令式模式的相當直接的翻譯支持,例如http://learnyouahaskell.com/a-fistful-of-monads#do-notation
(我知道在某種意義上,do-notation 仍然“真正”起作用;這里的重點是它允許對一些命令式設計模式進行相當直接的翻譯。)
我感興趣的一種模式是函式需要更新外部變數,即存在于與其他代碼共享的外部范圍中的變數。這可以在 Python 中簡單地演示:
def three():
n = 0
def inc():
nonlocal n
n = 1
inc()
inc()
inc()
return n
是否有可能在 Haskell 中實作上述設計模式,也許有一些 do-notation 變體或其他方式?如果是這樣,怎么做?
要明確這個問題的范圍:
我不是在問在 Haskell 中解決上述問題的最佳方法是什么。顯然,答案是three = 3。這只是一個例子。
我不是在問上面的設計模式是好是壞。顯然,這將是一個見仁見智的問題。
我不是在問人們在撰寫 Haskell 時應該如何努力避免使用命令式設計模式。顯然,這也是一個見仁見智的問題。
我只是問上面的設計模式是否可以在 Haskell 中實作,如果可以,如何實作。
uj5u.com熱心網友回復:
在 Haskell 中,您所要做的就是在外部作用域中創建可變變數(實際上是對它的參考)并在內部作用域中使用它。
在這里,我使用了ST smonad 來說明原理,但是您可以使用IO和許多其他型別的參考來做同樣的事情。
import Control.Monad.ST
import Data.STRef
three :: ST s Int
three = do
n <- newSTRef 0
let inc = modifySTRef' n ( 1)
inc
inc
inc
readSTRef n
main :: IO ()
main = print (runST three) -- output: 3
請注意,在一般情況下,inc可能是一個大塊do,可能在其范圍內創建新的參考(新的區域變數),并擁有自己的內部塊。與在 python 中一樣,范圍的嵌套沒有限制。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/423014.html
標籤:
