2017-03-05 32 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) }