0
我试图使用状态单声道的简单变量,它的工作。但在这里,似乎我正在尝试混合IO和非IO。 打算有一个由Monad管理的数组。我想读取和写入这个数组。状态单声道混合IO和非IO
似乎比我想象的更难。
funarray :: Map.Map String (IOArray Int Int)
funarray = Map.empty
storearray :: String -> (IOArray Int Int)-> State (Map.Map String (IOArray Int Int))()
storearray x value = do
funarray <- get
put (Map.insert x value funarray)
retrievearray :: String -> State (Map.Map String (IOArray Int Int)) (Maybe ((IOArray Int Int)))
retrievearray arr = do
funarray <- get
return (Map.lookup arr funarray)
putmutablearray = do {
arr <- newArray (512,512) 0 ;
storearray "value-table" arr
}
getmutablearray = do { retrievearray "value-table";}
putthenget = do {putmutablearray; getmutablearray;}
value :: BoardState -> IO Int
value (BoardState xloc oloc index) = do {
arr <- (runState putthenget funarray);
v <- (readArray arr index);
return v
}
以此开始的多个错误。
* Couldn't match expected type `IOArray Int Int'
with actual type `IO (IOArray Int Int)'
* In the second argument of `storearray', namely `createarray'
In a stmt of a 'do' block: storearray "value-table" createarray
In the expression: do { storearray "value-table" createarray }
我可以混合它们吗?这是一个全局数组。大一个。我需要大型机器学习任务。
更新:在一种命令式语言中,我会将其存储在全局中。
createarray :: IO (IOArray Int Int)
createarray = do {
arr <- newArray (512,512) 0;
return arr
}
这种感觉有点像您在解决问题时遇到了问题。你能否给我们多一点你想达到的内容? – epsilonhalbe
请这么友善,并为所有函数定义添加签名 - 因此您可以确保您的函数符合预期 – epsilonhalbe
看起来好像您要更新状态monad中的状态并执行IO访问(到数组)。你不能同时做到这一点:无论你是在单态还是在IO单元中工作。如果你想要做到这一点,你必须选择一个monad,它既允许例如'StateT(IOArray ...)IO',使用monad变换器和'liftIO'嵌入IO操作。不过,这需要对monads有一些深入的了解。但是,也许你需要的比这简单得多。你应该更好地解释你的任务:使用状态monad + IO数组+ IO + Map有点奇怪。 – chi