2017-03-05 74 views
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 
       } 
+1

這種感覺有點像您在解決問題時遇到了問題。你能否給我們多一點你想達到的內容? – epsilonhalbe

+1

請這麼友善,併爲所有函數定義添加簽名 - 因此您可以確保您的函數符合預期 – epsilonhalbe

+0

看起來好像您要更新狀態monad中的狀態並執行IO訪問(到數組)。你不能同時做到這一點:無論你是在單態還是在IO單元中工作。如果你想要做到這一點,你必須選擇一個monad,它既允許例如'StateT(IOArray ...)IO',使用monad變換器和'liftIO'嵌入IO操作。不過,這需要對monads有一些深入的瞭解。但是,也許你需要的比這簡單得多。你應該更好地解釋你的任務:使用狀態monad + IO數組+ IO + Map有點奇怪。 – chi

回答

0

我自己的答案。我認爲這是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) }