Я пытаюсь изучить трансформаторы монады и есть проблемы, чтобы найти объяснение одной проблемы.MaybeT monad transformer change Writer to WriterT
Скажем, я создаю писатель (в GHCI), как это:
let w = writer (Just "value", ["log"]) :: Writer [String] (Maybe String)
А теперь я хочу, чтобы обернуть его в MaybeT
монады трансформатора. MaybeT
конструктор имеет следующий вид:
:t MaybeT
m (Maybe a) -> MaybeT m a
и, основываясь на этом, результат вызова MaybeT
с w
должны иметь тип:
MaybeT (Writer [String]) String
Но это не делает:
let mt = MaybeT w
:t mt
MaybeT (WriterT [String] Data.Functor.Identity.Identity) String
Мой вопрос в том, почему ghci заменяет Writer [String]
на WriterT [String] Identity
? Я вообще этого не понимаю, но у меня есть сильное чувство, что я что-то пропустил.
Это то же самое: 'Writer a' является синонимом типа' WriterT a Identity'. – zakyggaps
В старых версиях библиотек вы получили ожидаемый результат. Однако в новых версиях используются монадные трансформаторы «все в порядке», а монады, такие как «Читатель» и «Писатель», определяются с помощью соответствующего трансформатора («Читатель» и «WriterT») и использования монады «Идентичность» (которая «ничего не делает»)). «Читатель» - это просто синоним типа. При объединении этих типов синоним расширяется, и вы видите фактический тип. – Bakuriu
'writer' на самом деле:' writer :: Monad m => (a, w) -> WriterT wma' и 'Writer wa = WriterT w Identity a' - в вашем случае' m = Identity', 'a = Maybe String 'и' w = [String] '- последний аргумент (здесь' a') * curried * в других комментариях и для 'MaybeT' (потому что первый компонент' MaybeT' должен иметь вид '* -> *' ') (PS: * curried * на самом деле не является [правильной концепцией] (https://en.wikipedia.org/wiki/Lambda_calculus#.CE.B7-conversion), но я надеюсь, что вы понимаете, что я говорю) – Carsten