4

这部分http://book.realworldhaskell.org/read/monad-transformers.html#id659032来自《Real World Haskell》一书,建议在编写新的 Monad Transformer 时,我们必须手动派生 、 等MonadState的实例。MonadIO

但我尝试了以下并编译。为什么不在图书馆做呢?

假设我有MaybeT单子变压器:

newtype MaybeT m a = MaybeT {
    runMaybeT :: m (Maybe a)
}

instance Monad m => Monad (MaybeT m) where -- blah blah

instance MonadTrans MaybeT where
    lift = MaybeT . (liftM Just)

那么一旦我们知道这t是 aMonadTrans并且m是 a Monad,为什么不能像这样自动导出其他所有内容?

instance (MonadTrans t, Monad (t m), MonadIO m) => MonadIO (t m) where
    liftIO = lift . liftIO

instance (MonadTrans t, Monad (t m), MonadState s m) => MonadState s (t m) where
    get = lift get
    put = lift . put

作者的意思是我们必须为每个新的手动执行此操作,MonadTrans否则我误解了他的意思?

非常感谢你 :)

4

1 回答 1

4

他们不这样做的原因很简单:

  1. 首先,如果他们添加这个会破坏很多旧代码,因为你需要一些东西,比如UndecidableInstances让 GHC 在自动和手动定义的实例之间做出决定。这将非常麻烦。
  2. 什么,如果你想定义一个与上面不同的实例,可能是出于性能原因或做一些黑客行为?如果这个实例是内置的,我认为这个小样板比定义自定义实例的无能/更高的成本(因为告诉 GHC 你想要哪个实例的诡计)更可取。
于 2010-12-06T10:04:02.187 回答