Почему шаблон при написании новых монад трансформаторов - PullRequest
4 голосов
/ 06 декабря 2010

Этот раздел 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 - это MonadTrans и m это 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, или я ошибаюсь?

Большое спасибо:)

1 Ответ

4 голосов
/ 06 декабря 2010

Причина, по которой они этого не делают, очень проста:

  1. Во-первых, было бы сломано много старого кода, если бы они добавили это, потому что вам нужно что-то вроде UndecidableInstances, чтобы позволить GHC выбирать между автоматическим и заданным вручную экземпляром. Это было бы очень громоздко.
  2. Что, если вы хотите определить экземпляр, отличный от приведенного выше, возможно, по соображениям производительности или для какого-нибудь взлома? Я думаю, что этот маленький пример предпочтительнее, чем невозможность / более высокая стоимость (из-за хитрости, чтобы сказать GHC, какой экземпляр вы хотите) определения настраиваемых экземпляров, если этот экземпляр будет встроенным.
...