Ответ 1
Непосредственный ответ на ваш вопрос: нет, нет стандартной библиотеки, которая предоставляет это. Кроме того, версия, которую вы предложили, по-прежнему будет протекать. Единственная версия, которую я знаю, которая не течет, - это симулировать WriterT
с помощью строгой StateT
. Я написал очень подробный e-mail об этом в список рассылки библиотек Haskell, сравнивающий строгость и производительность нескольких реализаций. Короче говоря: реализация WriterT
как строгая StateT
не только устраняет утечки пространства, но также генерирует очень эффективный код.
Вот работа, которая сработала:
newtype WriterT w m a = WriterT { unWriterT :: w -> m (a, w) }
instance (Monad m, Monoid w) => Monad (WriterT w m) where
return a = WriterT $ \w -> return (a, w)
m >>= f = WriterT $ \w -> do
(a, w') <- unWriterT m w
unWriterT (f a) w'
runWriterT :: (Monoid w) => WriterT w m a -> m (a, w)
runWriterT m = unWriterT m mempty
tell :: (Monad m, Monoid w) => w -> WriterT w m ()
tell w = WriterT $ \w' ->
let wt = w `mappend` w'
in wt `seq` return ((), w `mappend` w')
Я бы хотел, чтобы это было добавлено в transformers
в какой-то момент, но есть некоторые незначительные проблемы, которые необходимо устранить (например, имя модуля должно быть для одного).