Почему монады-трансформаторы не имеют ограничений для получения монад? - программирование
Подтвердить что ты не робот

Почему монады-трансформаторы не имеют ограничений для получения монад?

В MonadTrans класс:

class MonadTrans t where
    -- | Lift a computation from the argument monad to the constructed monad.
    lift :: Monad m => m a -> t m a

почему нет t m, ограниченного быть Монадой? то есть почему:

{-# LANGUAGE MultiParamTypeClasses #-}
class Monad (t m) => MonadTrans t m where
  lift :: Monad m => m a -> t m a

Если ответ "потому что это так, как есть", это прекрасно - это просто запутывает для n008.

4b9b3361

Ответ 1

Вы предложили следующее:

class Monad (t m) => MonadTrans t m where
    lift :: Monad m => m a -> t m a

... но действительно ли это означает, что вы хотите? Кажется, вы хотите выразить что-то вроде "тип t может быть экземпляром MonadTrans, если для всех m :: * -> *, где m является экземпляром Monad, t m также является экземпляром Monad".

То, что на самом деле говорит выше определение класса, больше похоже на "types t и m может составлять экземпляр MonadTrans, если для этих конкретных типов t m является экземпляром Monad". Внимательно изучите разницу и подразумеваемый потенциал для случаев, которые могут быть не такими, какие вы хотите.

В общем случае каждый параметр класса типа является независимым "аргументом", который был щедрым источником как головных болей, так и расширений GHC, поскольку люди пытались использовать MPTC.

Это не означает, что такое определение не может быть использовано в любом случае - как вы указываете, текущее определение также не является идеальным. Возрастная проблема "Почему Data.Set Is not a Functor" связана, и такие проблемы помогли мотивировать недавний tomfoolery ConstraintKinds.

Окончательный ответ на "почему не" здесь почти наверняка таков, что дается Даниэлем Фишером в комментариях, потому что MonadTrans - довольно основная функциональность, было бы нежелательно зависеть от какого-то страшного каскада все более тайного Расширения GHC.