Haskell 如何为非转换器的monad定义MonadBaseControl?
不幸的是(但可以理解的是)作者放弃了Haskell 如何为非转换器的monad定义MonadBaseControl?,haskell,monad-transformers,Haskell,Monad Transformers,不幸的是(但可以理解的是)作者放弃了monad控件。但是,这不是我的选项,因为我需要在自定义monad中使用Control.Concurrent.Async.Lifted: {-# LANGUAGE DataKinds, GADTs, ScopedTypeVariables #-} data FeatureFlag = Feature1 | Feature2 newtype AppM (features :: [FeatureFlag]) a = AppM (ReaderT Env IO a
monad控件
。但是,这不是我的选项,因为我需要在自定义monad中使用Control.Concurrent.Async.Lifted
:
{-# LANGUAGE DataKinds, GADTs, ScopedTypeVariables #-}
data FeatureFlag = Feature1 | Feature2
newtype AppM (features :: [FeatureFlag]) a = AppM (ReaderT Env IO a)
deriving (Functor, Applicative, Monad, MonadReader Env, MonadIO, MonadThrow, MonadCatch, MonadMask, MonadUnliftIO)
我试过阅读,但对我来说似乎没有什么意义。从概念上讲,我理解为什么需要使用MonadBaseControl和friends,这要归功于at的演练,但我不知道如何实现这一点
官方文档顶部有一个实施指南,但它假设monad transformers:
使用T的构造函数和解构器上的defaultLiftWith和defaultRestoreT函数,为所有转换器T定义实例MonadTransControl T
[……]
为所有变压器定义实例MonadBaseControl B m=>MonadBaseControl B(T m):
我如何为MonadBaseControl IO(AppM fs)
编写一个合理的实例,当monad被打开并再次包装时,fs
部分被保留?此外,我假设我实际上不必实现MonadTransControl
,因为AppM fs
不是一个转换器
PS:同样相关-您的
AppM
基本上是一个ReaderT
转换器;您刚刚将其专门化为IO
。您可以将其改写为:
newtype AppT (features :: [FeatureFlag]) m a = AppT (ReaderT Env m a)
使用IO版本的类型别名:
type AppM features = AppT features IO
然后,您应该能够使用普通派生子句和独立派生子句的组合来获得所需的类
至少,在下面的类型检查中,GHC似乎认为它生成了一个实例MonadBaseControl IO(AppT features IO)
如果您只是装载cult
ReaderT
的实例,会出现什么问题?因此我想到,如果unlift实例使用一些特性标记其状态,以防止通过unlifting写入AppT fs m a->AppT fs'm a
,可能会很好。也许这就是提问者最初的目的?
{-# LANGUAGE DataKinds, FlexibleInstances, GADTs, GeneralizedNewtypeDeriving,
KindSignatures, MultiParamTypeClasses, ScopedTypeVariables, StandaloneDeriving,
UndecidableInstances #-}
import Control.Monad.Base
import Control.Monad.Catch
import Control.Monad.Reader
import Control.Monad.IO.Unlift
import Control.Monad.Trans.Control
data FeatureFlag = Feature1 | Feature2
data Env
newtype AppT (features :: [FeatureFlag]) m a = AppT (ReaderT Env m a)
deriving (Functor, Applicative, Monad, MonadReader Env, MonadIO,
MonadThrow, MonadCatch, MonadMask,
MonadTrans, MonadTransControl)
type AppM features = AppT features IO
deriving instance MonadBase IO (AppM features)
deriving instance MonadBaseControl IO (AppM features)
deriving instance MonadUnliftIO (AppM features)