为什么我不能将值写入IORef但可以读取它

 咾爺們 发布于 2023-02-12 18:49

在haskell中,我需要一个全局变量,所以我选择使用IORef插槽,这是我的计划:

memo :: IORef Int
memo = unsafePerformIO $ newRefInt 9999

evaluate ARGs s = do
  v <- Right $ unsafePerformIO $ readIORef memo
  val <- Right $ VInt v
  return $ (val, s)

evaluate (Call funcID exp) s = do
...
Right $ writeIORef memo 100
...

我的计划是当执行者评估"呼叫"节点时,它会将参数保存到插槽中.然后,当评估"ARGs"节点时,将读取该备忘录槽.

但无论我做什么,我只能读取9999但不能在该槽中写入新值.

甚至我试过:

memo :: IORef Int
memo = unsafePerformIO $ newRefInt 9999

evaluate ARGs s = do
  Right $ writeIORef memo 100
  v <- Right $ unsafePerformIO $ readIORef memo
  val <- Right $ VInt v
  return $ (val, s)

这仍然会导致备忘录= 9999.为什么?

1 个回答
  • 因为写作也在IOmonad中.首先,很多人unsafePerformIO都很糟糕.unsafePerformIO 不应该在普通代码中使用.

    现在,您正在创建一个动作来写入IORef类型IO (),将其包装在Right构造函数中,然后将其丢弃,您实际上从未使用它.

    你不能这样unsafePerformIO做,因为你对Either你构造的价值没有严格要求.这就是为什么unsafePerformIO不好的原因,如果事情要发生的话,很难理解.

    而是试试

     evaluate ARGs s = do
        liftIO $ writeIORef memo 100
        v <- liftIO $ readIORef memo
        val <- return $ VInt v
        return $ (val, s)
    

    并使用EitherTmonad变换粘IO在那里.

    2023-02-12 18:51 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有