2012-06-25 30 views
2

我有以下几点:读者单子并输入变量

type KEY = (IPv4, Integer) 
type TPSQ = TVar (PSQ.PSQ KEY POSIXTime) 
type TMap a = TVar (Map.Map KEY [a]) 

data Qcfg a = Qcfg { qthresh :: Int, tdelay :: Rational, cwpsq :: TPSQ, cwmap :: TMap a 
, cwchan :: TChan String } 

getTMap = do 
    c <- ask 
    return (cwmap c) 

,并得到有关读者单子的错误:

No instance for (MonadReader (Qcfg a2) m2) 
     arising from a use of `ask' 
    Possible fix: 
     add an instance declaration for (MonadReader (Qcfg a2) m2) 
    In a stmt of a 'do' expression: c <- ask 
    In the expression: 
     do { c <- ask; 
      return (cwmap c) } 
    In an equation for `getTMap': 
     getTMap 
      = do { c <- ask; 
       return (cwmap c) } 

我对读者单子不够默契还没有确定如何解决这个问题。

[编辑] 添加类型签名适用于涉及类型变量的部分,但会为其余部分创建错误。例如。

getTMap :: Reader (Qcfg a) (TMap a) 
getTMap = do 
    c <- ask 
    return (cwmap c) 

getTPsq :: Reader (Qcfg a) TPSQ 
getTPsq = do 
    c <- ask 
    return (cwpsq c) 
... 
let q = getTPsq 
qT <- atomically $ readTVar q 

结果

Couldn't match expected type `TVar a0' 
       with actual type `ReaderT 
            (Qcfg a1) Data.Functor.Identity.Identity TPSQ' 
    Expected type: TVar a0 
     Actual type: Reader (Qcfg a1) TPSQ 
    In the first argument of `readTVar', namely `q' 
    In the second argument of `($)', namely `readTVar q' 
+1

你可以写'getTMap =问>> =回报。 cwmap'。 – JJJ

回答

5

你只需要提供一个类型签名:

getTMap :: Reader (Qcfg a) (TMap a) 
getTMap = do 
    c <- ask 
    return (cwmap c) 
+0

适用于引用的问题,但导致我陷入其余的麻烦。编辑了我的问题。 –

+0

(a)当某人提供了答案(b)您没有提供代码的许多相关部分时,改变问题是一种糟糕的形式,例如什么是'TPSQ'? (c)错误信息告诉你你的代码有什么问题 - 它期待一个'TVar a',但你给它一个'Reader(Qcfg b)TPSQ'。 –

+0

谢谢。在我上面的问题是,它需要读取'let q = runReader getTPsq qcfg'。 –