问题:是否有一种方法可以“存储”超出控制结构的值
免责声明:以下代码框架毫无意义->仅用于更好地理解问题...
控制结构可以执行任何操作->这就是为什么我不希望像结构那样返回值的原因是正常功能...
->在这种情况下,您也不能只使用更改后的值来递归调用foo函数,因为foo函数必须先跳转,然后才能进入它离开的控件结构...等等...
foo = do
val1 <- return 2
val2 <- return 0
_ <- if True then do
val1 <- return 3
(...)
val2 <- return 6
(...)
return ()
else
return ()
_ <- putStrLn $ show(val1) ++ show(val2)
return ()
答案 0 :(得分:6)
您可以使用State monad:
import Control.Monad.Trans.State
data MyState = MyState { val1 :: Int, val2 :: Int } deriving (Eq, Show)
foo :: State MyState String
foo = do
put $ MyState { val1 = 2, val2 = 0 }
if True
then do
modify (\s -> s { val1 = 3 })
-- ...
modify (\s -> s { val2 = 6 })
else
return ()
MyState v1 v2 <- get
return $ show v1 ++ show v2
GHCi:
*Q55856229> runState foo $ MyState 0 0
("36",MyState {val1 = 3, val2 = 6})
答案 1 :(得分:3)
也许您想要这样的东西。请记住,<-
是绑定的,而不是赋值的,因此您无法重新定义变量。
foo = do
(val1, val2) <- if True then do
val1 <- return 3
(...)
val2 <- return 6
(...)
return (val1, val2)
else
return (2, 0)
_ <- putStrLn $ show(val1) ++ show(val2)
return ()
如果您绝对必须具有变异变量,则需要IORef
,STRef
之类的东西,或者是State
monad或StateT
转换器。很难用OP发布的信息来说明。