代码之家  ›  专栏  ›  技术社区  ›  SkyWriter

在WriterT中包装Maybe以添加日志记录

  •  3
  • SkyWriter  · 技术社区  · 10 年前

    我完全被困了,我觉得我现在需要一些帮助,只是为了保持清醒。我想要一些简单的东西,比如向返回 Maybe ,但无论我怎么努力,我都不能把类型弄对。

    这是(据我所知)我能得到的最接近的:

    import Data.Maybe
    import Control.Monad
    import Control.Monad.Writer
    
    q :: Integer -> Maybe Integer
    q x = if x > 7
          then Just x
          else Nothing
    
    qlog :: Integer -> WriterT [String] Maybe Integer
    qlog x = do
      tell ["Querying " ++ show x]
      return $ q x
    

    这仍然会产生一个键入错误:

    Couldn't match type ‘Maybe Integer’ with ‘Integer’
    Expected type: WriterT [String] Maybe Integer
      Actual type: WriterT [String] Maybe (Maybe Integer)
    In a stmt of a 'do' block: return $ q x
    In the expression:
      do { tell ["Querying " ++ show x];
           return $ q x }
    In an equation for ‘qlog’:
        qlog x
          = do { tell ["Querying " ++ show x];
                 return $ q x }
    

    我应该如何调整代码以使其编译和工作?

    非常感谢你的帮助,哈斯凯勒兄弟!

    1 回复  |  直到 10 年前
        1
  •  3
  •   behzad.nouri    10 年前

    为了进行类型检查,内部monad应该是 lifted :

    lift :: (Monad m, MonadTrans t) => m a -> t m a
    

    所以,代替 return $ q x 你需要写: lift $ q x ; 如:

    qlog :: Integer -> WriterT [String] Maybe Integer
    qlog x = do
      tell ["Querying " ++ show x]
      lift $ q x
    
    推荐文章