我正在尝试学习 Haskell,并且正在尝试使用 IORef 来保存和查找记录。我的代码看起来像这样(请注意,我在此示例中选择“String”作为 IORef 类型只是为了方便和简洁,在我的实际代码中我使用的是记录。并且还忽略了我使用的是 Set 代替的地图,我会改变它):
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"
我想要实现的是在两个函数调用之间共享状态(Set),以便findStringInState
可以返回String
我刚刚插入到 Set 中的状态。但是当我运行这个doStuff
函数时,我得到了这个:
*MyTest> doStuff
### saved: fromList ["string1"]
Looking for string1 in: fromList []
Nothing
我可能误解了一些东西,因为我认为 IORef 确实应该是我的状态的容器。
- 为什么这不起作用?
- 我该怎么做才能让它发挥作用?