将值保存在控制结构之外
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将值保存在控制结构之外相关的知识,希望对你有一定的参考价值。
问题:有没有办法将值存储在控制结构之外
免责声明:以下代码框架没有任何真正的意义 - >它只是为了更好地理解问题...
控制结构可以做“任何事情” - >这就是为什么我不想返回值,因为结构将是一个正常的函数...
- >在这种情况下你也不能只是用改变的值来调用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 ()
答案
你可以使用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})
另一答案
也许你想要这样的东西。请记住,<-
是绑定,而不是赋值,因此您无法重新定义变量。
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发布的信息。
以上是关于将值保存在控制结构之外的主要内容,如果未能解决你的问题,请参考以下文章