我不了解 Haskell 单子背后的确切代数和理论。然而,当我考虑一般的函数式编程时,我得到的印象是,状态将通过获取初始状态并生成它的副本来表示下一个状态来建模。这就像将一个列表附加到另一个列表时一样;两个列表都没有被修改,但第三个列表被创建并返回。
因此,将一元操作视为隐式地将初始状态对象作为参数并隐式返回最终状态对象是否有效?这些状态对象将被隐藏,这样程序员就不必担心它们并控制它们的访问方式。因此,程序员不会像十分钟前那样尝试复制表示 IO 流的对象。
换句话说,如果我们有这个代码:
main = do
putStrLn "Enter your name:"
name <- getLine
putStrLn ( "Hello " ++ name )
...可以将 IO monad 和“do”语法视为代表这种代码风格吗?
putStrLn :: IOState -> String -> IOState
getLine :: IOState -> (IOState, String)
main :: IOState -> IOState
-- main returns an IOState we can call "state3"
main state0 = putStrLn state2 ("Hello " ++ name)
where (state2, name) = getLine state1
state1 = putStrLn state0 "Enter your name:"