Трансформаторы Monad и функция лифта

Почему нет необходимости использовать лифт для выполнения функции во внутренней среде преобразователя монад, кроме ввода-вывода? Я имею в виду, что если у меня StateT поверх WriterT и WriterT над ReaderT, почему я могу это сделать?

tell $ {- any code here for the Writer -}
foo <- asks {- This for the reader -}
and so on...

вместо того

lift $ tell $ {- code ... -}
...

Есть ли какое-то особое объяснение или это только способ написания Трансформеров Монад?


person Jcao02    schedule 20.06.2013    source источник
comment
Посмотрите на все экземпляры WriterT.   -  person icktoofay    schedule 20.06.2013
comment
Обратите внимание, что если вы используете библиотеку transformers вместо mtl, вам придется явно lift все.   -  person Gabriel Gonzalez    schedule 20.06.2013


Ответы (1)


Это потому, что библиотека преобразователей монад (MTL) признает, что довольно часто вы складываете монады таким образом, поэтому они не определяют tell как просто некоторую функцию (Mondoid w) => w -> Writer ().

Вместо этого у них есть MonadWriter который определяется как класс типов с функцией tell как в нем. Затем они определяют массу экземпляров MonadWriter: ReaderT, IO, Writer (да) и т. Д. И, таким образом, вы избегаете надоедливого повторения lift..

Это довольно распространенное явление, любой преобразователь монад (в MTL) будет иметь Control.Monad.***.Class, который имеет такой класс типов.

person Daniel Gratzer    schedule 20.06.2013
comment
Я понимаю !, я не читал экземпляры Монад. Спасибо - person Jcao02; 20.06.2013