Я пытаюсь создать преобразователь монад для будущего проекта, но, к сожалению, моя реализация функции типа монад (>> =) не работает.
Прежде всего, вот реализация базовой монады:
newtype Runtime a = R {
unR :: State EInfo a
} deriving (Monad)
Здесь реализация типа Монады осуществляется GHC автоматически (с использованием языковой прагмы GeneralizedNewtypeDeriving
).
Монадный трансформатор определяется так:
newtype RuntimeT m a = RuntimeT {
runRuntimeT :: m (Runtime a)
}
Проблема возникает из-за того, что я инстанцирую (>> =) функцию типа монады:
instance (Monad m) => Monad (RuntimeT m) where
return a = RuntimeT $ (return . return) a
x >>= f = runRuntimeT x >>= id >>= f
Как я понимаю, первый >>=
работает в базовой монаде m
. Таким образом, runRuntimeT x >>=
возвращает значение типа Runtime a
(верно?). Затем следующий код id >>=
должен вернуть значение типа a
. Это значение передается функции f типа f :: (Monad m) => a -> RuntimeT m b
.
И здесь возникает проблема с типом: тип функции f
не соответствует типу, требуемому функцией (>> =). Как я могу сделать это связным? Я понимаю, почему это не работает, но мне не удается превратить это во что-то функциональное.
Редактировать: Сообщение об ошибке:
Core.hs:34:4:
Occurs check: cannot construct the infinite type: m = RuntimeT m
When generalising the type(s) for `>>='
In the instance declaration for `Monad (RuntimeT m)'
Failed, modules loaded: none.
Спасибо за вашу помощь, и не стесняйтесь исправлять любые недостатки в моем сообщении,
Чарли П.