14

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限制为 Monad?即,为什么不:

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

如果答案是“因为它就是这样”,那很好——这只是让 n008 感到困惑。

4

1 回答 1

14

您提出以下建议:

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

...但这真的意味着你想要的吗?似乎您想表达类似“一个类型t可能是MonadTransif 的实例,对于所有m :: * -> *wherem的实例Monadt m也是Monad”的实例。

上面的类定义实际上说的更像是“类型t并且m可能构成MonadTransif 的实例,对于那些特定类型,t mMonad”的实例。仔细考虑差异,以及可能不是您想要的实例的隐含潜力。

在一般情况下,类型类的每个参数都是一个独立的“参数”,当人们尝试使用 MPTC 时,这一事实一直是令人头疼和 GHC 扩展的丰富来源。

这并不是说无论如何都不能使用这样的定义-正如您所指出的,当前的定义也不理想。古老的问题“为什么Data.Set不是Functor”是相关的,这些问题有助于激发最近的ConstraintKinds愚蠢行为。

这里“为什么不”的最终答案几乎可以肯定是 Daniel Fischer 在评论中给出的答案——因为MonadTrans它是非常核心的功能,所以不希望让它依赖于一些越来越神秘的 GHC 扩展的可怕级联。

于 2012-12-03T17:10:27.143 回答