Wrapping Возможно в WriterT добавить логирование

Я полностью застрял и чувствую, что теперь могу использовать некоторую помощь, просто чтобы оставаться в здравом уме. Я хочу что-то столь же простое, как добавление возможностей регистрации в функцию, которая возвращает 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 ответ

Решение

Для проверки типа следует поднять внутренние монады:

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
Другие вопросы по тегам