【发布时间】:2014-09-12 00:54:07
【问题描述】:
Applicative 转换器类在哪里?我想为applicative transformer stack in a previous answer 使用转换器类,但它们似乎不存在。
transformers 包和许多其他包都充满了保留Applicative 结构的转换器,即使底层结构不是Monad。
快速浏览一下transformers,大多数转换器都有Applicative 实例。
Applicative f => Applicative (Backwards f)
Applicative f => Applicative (Lift f)
Applicative (ContT r m)
Applicative m => Applicative (IdentityT m)
Applicative m => Applicative (ReaderT r m)
(Monoid w, Applicative m) => Applicative (WriterT w m)
(Applicative f, Applicative g) => Applicative (Compose f g)
(Applicative f, Applicative g) => Applicative (Product f g)
只有状态和交替的转换器(ExceptT 和 MaybeT)需要 Applicative 实例的底层 monad。
(Functor m, Monad m) => Applicative (ExceptT e m)
(Functor m, Monad m) => Applicative (MaybeT m)
(Monoid w, Functor m, Monad m) => Applicative (RWST r w s m)
(Functor m, Monad m) => Applicative (StateT s m)
Monad 转换器有一个类。我可以看到某些东西可能需要这个 Monad 约束,因为它不能在其他地方引入。
class MonadTrans t where
lift :: (Monad m) => m a -> t m a
Applicative 变形金刚的课程在哪里?
class ApTrans t where
liftAp :: (Applicative f) => f a -> t f a
或者只是普通的旧变形金刚(虽然我无法想象这有什么规律)?
class Trans t where
liftAny :: f a -> t f a
由于仅在多态约束方面的差异,这些类型类具有奇怪的变化模式。除了必须考虑无法表达的约束的定律之外,任何Trans 的实例都应该自动成为ApTrans 和MonadTrans 的实例,而任何ApTrans 的实例都应该自动成为ApTrans 的实例MonadTrans.
如果我们继续使用 mtl 库,那里的类也与 Applicative 转换器堆栈不兼容。我熟悉的所有 mtl 类都有 Monad 约束。例如这里是MonadReader
class Monad m => MonadReader r m | m -> r where
-- | Retrieves the monad environment.
ask :: m r
ask = reader id
-- | Executes a computation in a modified environment.
local :: (r -> r) -- ^ The function to modify the environment.
-> m a -- ^ @Reader@ to run in the modified environment.
-> m a
-- | Retrieves a function of the current environment.
reader :: (r -> a) -- ^ The selector function to apply to the environment.
-> m a
reader f = do
r <- ask
return (f r)
Monad 约束的目的是什么?它使上述许多转换器的MonadReader 和MonadReader 实例与Applicative 转换器堆栈不兼容。
我会天真地写一些类似的东西
class Reader r m | m -> r where
ask :: m r
local :: (r -> r) -> m a -> m a
甚至将local 拆分为一个单独的类。
class Reader r m | m -> r where
ask :: m r
class (Reader r m) => Local r m | m -> r where
local :: (r -> r) -> m a -> m a
如果没有Monad 实例,local 可能很难使用。没有Monad 约束的更有用的界面类似于
class (Reader r m) => Local r m | m -> r where
local :: m (r -> r) -> m a -> m a
是否存在没有Monad 约束的现有转换器类,或者是否实际需要另一个转换器类库?
【问题讨论】:
-
This 值得一读以各种方式组合应用程序。
-
@AndrewC 谢谢,我希望我在尝试回答链接的问题之前已经阅读过。
-
我认为有些应用转换器不是来自组合应用程序。例如,定义一元流
data MStream m a = MStream (a, MStream m a)。那么MStream Identity是一个Applicative,对于任何一个Applicative m,MStream m都是一个Applicative,通过无限重复有一个明显的lift :: m a -> MStream m a。然而,MStream m不是MStream和m的组合! (运动,是什么?) -
@Turion
MStream m a是Applicative,无论m是什么;m是一种幻象类型。与data Stream a = Stream a (Stream a)相同。如果您的意思是将as 包裹在m中,那么它正是ApplicativesStream和m、Compose Stream m的组合。这就是编写Applicatives 所做的;它将每次出现的参数都用内部函子包装到外部函子。 -
@Cirdec,我的评论中有一个根本性的错字。我的意思是
MStream m (a, MStream m a)!!
标签: haskell monad-transformers applicative