派生MonadThrow,MonadCatch,MonadBaseControl,MonadUnliftIO等是否安全?

时间:2019-07-03 05:59:04

标签: haskell monads monad-transformers deriving

我正在重构一些旧代码,这些代码是多态的但受类限制的monad:

class ( MonadIO m
      , MonadLogger m
      , MonadLoggerIO m
      , MonadThrow m
      , MonadCatch m
      , MonadMask m
      , MonadBaseControl IO m
      , MonadUnliftIO) => HasLogging m where

在较旧的代码中,应用程序的主要monad是...

type AppM = ReaderT Env IO

...现在将更改为...

newtype AppM (features :: [FeatureFlag]) a = AppM (ReaderT Env IO a)
  deriving (Functor, Applicative, Monad, MonadReader Env, MonadIO)

在这种情况下,自动导出以下内容是否安全:

  • MonadThrow
  • MonadCatch
  • MonadMask
  • MonadBaseControl
  • MonadUliftIO

无需深入了解GHC的内部原理,当编译器自动地推导事物时,对直觉发生的事情有最好的直觉是什么?

1 个答案:

答案 0 :(得分:1)

该用户手册包含有关每个扩展的文档,并且一直在不断完善。这是有关派生的部分,应该足以了解实际发生的情况:https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extensions-to-the-deriving-mechanism

在这种情况下,所有这些类均由GeneralizedNewtypeDeriving处理。

{-# LANGUAGE GeneralizedNewtypeDeriving, UndecidableInstances #-}

module M where

import Control.Monad.IO.Unlift
import Control.Monad.Catch
import Control.Monad.Trans.Control
import Control.Monad.Base
import Control.Monad.Reader

newtype Foo a = Foo (ReaderT () IO a)
  deriving (Functor, Applicative, Monad, MonadIO, MonadUnliftIO, MonadThrow, MonadCatch, MonadMask, MonadBase IO, MonadBaseControl IO)

通常,用户定义类的三个相关扩展为GeneralizedNewtypeDerivingDerivingViaDeriveAnyType。并且值得启用DerivingStrategies来明确显示正在使用哪个。