簡體   English   中英

初始化后返回TVar

[英]return TVar after initialisation

是否可以在do塊中返回新創建的TVar? 我嘗試使用以下代碼實現此目的:

type Buffer a = TVar [[(a,a)]]

newBuffer :: STM (Buffer a)
newBuffer = newTVar [[]]

launchGhosts :: [[(String,String)]] -> Buffer String
launchGhosts unblocked = do buff <- atomically newBuffer
                            atomically $ put buff unblocked
                            return buff


computeBlock :: Buffer String -> IO()
computeBlock buff = do i <- atomically $ get buff
                       putStrLn $ show i

put :: Buffer a -> [[(a,a)]] -> STM ()
put buff x = do writeTVar buff x

get :: Buffer a -> STM [[(a,a)]]
get buff = do x <- readTVar buff
              return x

這應該允許我初始化共享內存,並在程序的其他位置使用它。 我想要分離內存初始化的主要原因是多次調用並發函數,而不必一次又一次地初始化內存。

類型檢查器引發以下兩個錯誤:

pacman.hs:65:29:
No instance for (Monad TVar)
  arising from a do statement
Possible fix: add an instance declaration for (Monad TVar)
In a stmt of a 'do' block: buff <- atomically newBuffer
In the expression:
  do { buff <- atomically newBuffer;
       atomically $ put buff unblocked;
       computeBlock buff;
       return buff }
In an equation for `launchGhosts':
    launchGhosts unblocked
      = do { buff <- atomically newBuffer;
             atomically $ put buff unblocked;
             computeBlock buff;
             .... }

pacman.hs:65:37:
    Couldn't match expected type `TVar t0' with actual type `IO a0'
    In the return type of a call of `atomically'
    In a stmt of a 'do' block: buff <- atomically newBuffer
    In the expression:
      do { buff <- atomically newBuffer;
           atomically $ put buff unblocked;
           computeBlock buff;
           return buff }

有誰知道問題出在哪里,或者是實現此代碼背后想法的另一種方式?

更新:

launchGhosts :: [[(String,String)]] -> IO(Buffer String)
launchGhosts unblocked = do buff <- atomically newBuffer
                            atomically $ put buff unblocked
                            return buff


computeBlock :: IO(Buffer String) -> IO()
computeBlock buff = do i <- atomically $ get buff
                       putStrLn $ show i

更新:

pacman.hs:71:46:
Couldn't match expected type `Buffer a0'
            with actual type `IO (Buffer String)'
In the first argument of `get', namely `buff'
In the second argument of `($)', namely `get buff'
In a stmt of a 'do' block: i <- atomically $ get buff

解決方案是將launchGhosts聲明為

launchGhosts :: [[(String,String)]] -> IO (Buffer String)

問題是您聲明launchGhosts返回了一個Buffer String ,它是TVar [[(String, String)]] 由於launchGhosts使用do塊,因此其結果類型需要一個Monad實例,根據您的簽名,該實例為TVar 這就是第一個錯誤。

另一個問題是, atomically類型為STM a -> IO a atomically newBuffer STM a -> IO a ,因此atomically newBufferIO something (實際類型)。 但是您在聲明為Buffer (即TVar )類型的do塊中使用它,因此它也應該具有該類型(預期類型)。 這就是第二個錯誤所在。

編輯:

為什么要更改computeBlock的類型簽名? 我從沒說過關於computeBlock事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM