2017-03-05 9 views
0

単純な変数のためにState Monadを使用しようとしました。しかし、ここでは、IOと非IOを混在させようとしているようです。 State Monadによって管理される配列を持つ意向。私はこの配列を読み書きしたい。State 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

状態モナドの状態を更新して(アレイに対して)IOアクセスを実行したいかのようです。あなたは同時にそれを行うことはできません:あなたは州のモナドかIOのどちらかで働いています。両方をしたい場合は、両方を許可するモナドを選択する必要があります。 'StateT(IOArray ...)IO'はモナド変換子を使用し、' liftIO'はIO動作を埋め込みます。しかし、これにはモナドの高度な理解が必要です。しかし、あなたが必要とするものはそれよりはるかに簡単です。あなたはあなたのタスクをよりよく説明する必要があります:状態モナド+ IOアレイ+ IO +マップを使用するのはちょっと変わったことです。 – chi

答えて

0

私自身の答えです。私はこれが熟語のハスケルの答えだと思う。他の専門家も意見を述べることができます。配列をグローバルにアクセスできるようにする方法がわかりません。私はそれが正しいとは言えませんハスケル。

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) } 
関連する問題