Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在使用IO时,如何在Haskell中的两个函数调用之间共享IORef状态?_Haskell_Shared State_Ioref - Fatal编程技术网

在使用IO时,如何在Haskell中的两个函数调用之间共享IORef状态?

在使用IO时,如何在Haskell中的两个函数调用之间共享IORef状态?,haskell,shared-state,ioref,Haskell,Shared State,Ioref,我正在尝试学习Haskell,并尝试使用IORef来保存和查找记录。我的代码是这样的(请注意,我在本例中选择“String”作为IORef类型只是为了方便和简洁,在我的实际代码中,我使用的是一个记录。同时忽略我使用的是集合而不是映射,我将对此进行更改): 我可能误解了一些东西,因为我认为IORef确实应该是我所在州的容器 为什么这不起作用 我能做些什么使它工作 似乎您将IO IORefState与IORefState(无IO)混淆,更一般地说,IO a与a 在您的情况下,IO IORefStat

我正在尝试学习Haskell,并尝试使用IORef来保存和查找记录。我的代码是这样的(请注意,我在本例中选择“String”作为IORef类型只是为了方便和简洁,在我的实际代码中,我使用的是一个记录。同时忽略我使用的是集合而不是映射,我将对此进行更改):

我可能误解了一些东西,因为我认为IORef确实应该是我所在州的容器

  • 为什么这不起作用
  • 我能做些什么使它工作

  • 似乎您将
    IO IORefState
    IORefState
    (无
    IO
    )混淆,更一般地说,
    IO a
    a

    在您的情况下,
    IO IORefState
    的值是动作
    newiorefempty
    ,它表示“从头开始创建新的
    IORef
    的动作”。
    相比之下,
    IORefState
    (不带
    IO
    )是正确的原始对象,您应该在使用它的函数之间共享它(
    saveStringToState
    ,和
    findStringInState
    )。
    然后,
    saveStringToState
    findStringInState
    分别调用
    newiorefempty
    ,即它们各自创建一个不同的
    IORefState
    对象,而另一个对象不会影响该对象

    要修复此问题,必须使用
    String->IO String调用
    newiorefempty
    (作为
    IO
    操作) ... findStringInState::IORefState->String->IO(可能是字符串) ... 让stateIO=newIORef为空 伊洛夫酒店
    module MyTest where
    
    import           Data.IORef
    import           Data.Set
    import           Data.Foldable          (find)
    
    type State = (Set String)
    type IORefState = IORef State
    
    saveStringToState :: IO IORefState -> String -> IO String
    saveStringToState stateIO string = do
      state <- stateIO
      atomicModifyIORef
        state
        (\oldStrings ->
           let updatedStrings = insert string oldStrings
           in (updatedStrings, updatedStrings))
      stringsState <- readIORef state :: IO State
      putStrLn ("### saved: " ++ show stringsState)
      return string
    
    findStringInState :: IO IORefState -> String -> IO (Maybe String)
    findStringInState stateIO soughtString = do
      state <- stateIO :: IO IORefState
      strings <- readIORef state :: IO State
      putStrLn ("Looking for " ++ soughtString ++ " in: " ++ show strings)
      return $ find (== soughtString) strings
    
    doStuff =
      let stateIO = newIORef empty
      in do saveStringToState stateIO "string1"
            findStringInState stateIO "string1"
    
    *MyTest> doStuff
    ### saved: fromList ["string1"]
    Looking for string1 in: fromList []
    Nothing
    
      saveStringToState :: IORefState -> String -> IO String
      ...
    
      findStringInState :: IORefState -> String -> IO (Maybe String)
      ...
    
      let stateIO = newIORef empty
      in do ioRef <- stateIO
            saveStringToState ioRef "string1"
            findStringInState ioRef "string1"
      -- Or, more simply:
      do ioRef <- newIORef empty
         saveStringToState ioRef "string1"
         findStringInState ioRef "string1"