У меня есть функция, которая сочиняет две монады:Почему `hoist` ограничивает параметр типа этой монады?
comp :: Monad m => m a -> m b -> m b
И два экземпляра таких монад, где на есть «внутри» Mfunctor
,
ms :: Monad m => m String
ms = undefined
tma :: (Monad m, MFunctor t) => t m a
tma = undefined
Теперь, если я пытаюсь составить ms
с tma
:
tmas = hoist (\ma -> comp ma ms) tma
Я получаю эту ошибку:
Could not deduce (a ~ [Char])
from the context (Monad m, MFunctor t)
bound by the inferred type of
comp :: (Monad m, MFunctor t) => t m b
at Coroutine.hs:607:1-40
`a' is a rigid type variable bound by
a type expected by the context: m a -> m a at Coroutine.hs:607:8
Expected type: m a
Actual type: m String
в котором говорится, что a
в ms
должен быть произвольного типа: ms :: Monad m => m a
.
Почему это и есть способ составить tma
с монадами определенных параметров.
Я могу видеть, что подпись тали:
hoist :: (Monad m, MFunctor t) => (forall a. m a -> n a) -> t m b -> t n b
, но не могу представить, как forall
влияет на то, что я пытаюсь сделать, если это имеет какой-либо эффект.
Спасибо за объяснение. Действительно ли присутствие 'forall' гарантирует некоторый уровень правильности? – chibro2