保存超出控制结构的值

时间:2019-04-25 19:16:12

标签: haskell

问题:是否有一种方法可以“存储”超出控制结构的值

免责声明:以下代码框架毫无意义->仅用于更好地理解问题...

控制结构可以执行任何操作->这就是为什么我不希望像结构那样返回值的原因是正常功能...

->在这种情况下,您也不能只使用更改后的值来递归调用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 ()

2 个答案:

答案 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 ()

如果您绝对必须具有变异变量,则需要IORefSTRef之类的东西,或者是State monad或StateT转换器。很难用OP发布的信息来说明。