如何将有状态计算应用于列表?

Rap*_*Mor 1 haskell state-monad

让我们想象一下Brainf*ck的虚拟子集:

+ 递增计数器

- 递减柜台

一个简单的程序:

program = "++++--" -- should evaluate to 2

有状态的评估功能:

eval :: Char -> State Int Char
eval '+' = do x <- get
              put (x + 1)
              return 'I'
eval '-' = do x <- get
              put (x - 1)
              return 'D'
Run Code Online (Sandbox Code Playgroud)

你会如何评价该计划?(fold对我来说看起来像是一个但是我无法理解它,并且它感觉不是正确的做法...)

Lee*_*Lee 7

您可以使用traverse_Data.Foldable:

import Data.Foldable (traverse_)
execState (traverse_ eval "++++--") 0
Run Code Online (Sandbox Code Playgroud)


C. *_*ley 5

您正在寻找的功能是sequence具有签名的功能sequence :: Monad m => [m a] -> m [a],并且在处理monad时非常常见State.

对于您的代码,您希望评估器看起来像这样:

evalBF :: String -> State Int String
evalBF = sequence . map eval
Run Code Online (Sandbox Code Playgroud)

然后你会用以下内容完全评估:

main :: IO ()
main = do
       src <- getLine
       print $ runState (evalBF src) 0
Run Code Online (Sandbox Code Playgroud)