State Monad混合IO和非IO

时间:2017-03-05 13:50:36

标签: haskell monads

我尝试使用State Monad作为简单变量,它可以工作。但在这里似乎我正在尝试混合IO和非IO。 打算由State Monad管理阵列。我想读写这个数组。

似乎比我想象的更难。

        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
              }

1 个答案:

答案 0 :(得分:0)

我自己的答案。我认为这是习惯性的Haskell答案。其他专家可以提出意见。不知道如何使数组全局可访问。我被告知这不是正确的Haskell。

   type ArrayAccess = ReaderT  (IOArray Int Int)  IO 
   type ArrayWriteAccess = ReaderT  (IOArray Int Int)  IO() 

   readvalue ::  Int -> ArrayAccess Int   
   readvalue x    = do 
   a <- ask
   b <- liftIO( readArray a x);    
   return b

   writevalue ::  Int -> Int -> ArrayWriteAccess   
   writevalue x y   = do 
   a <- ask
   liftIO( writeArray a x y)    

   -- Test array accesses
   readfromarray = do { a <- createarray; liftIO (runReaderT (readvalue 1) a) }
   writetoarray = do { a <- createarray; liftIO (runReaderT (writevalue 1 2) a) }