gpt4 book ai didi

haskell - 适用变压器类

转载 作者:行者123 更新时间:2023-12-04 05:49:41 25 4
gpt4 key购买 nike

Applicative 在哪里变压器类?我想为 applicative transformer stack in a previous answer 使用转换器类,但它们似乎不存在。

transformers包装和许多其他都充满了保存器Applicative的变压器结构,即使底层结构不是 Monad .

快速浏览 transformersApplicative大多数变压器的实例。

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)

只有状态和交替的转换器( ExceptTMaybeT )需要 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 的类(class)变压器。我可以看到某些东西可能需要这个 Monad约束,因为它不能在其他地方引入。
class MonadTrans t where
lift :: (Monad m) => m a -> t m a
Applicative 的类(class)在哪里?变压器?
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 的实例应该自动成为 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 的目的是什么?约束?它使 MonadReaderMonadReader许多上述转换器的实例与 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
local没有 Monad 可能很难使用实例。没有 Monad 的更有用的界面约束将类似于
class (Reader r m) => Local r m | m -> r where
local :: m (r -> r) -> m a -> m a

是否存在没有 Monad 的现有变压器类约束,还是实际需要另一个转换器类库?

最佳答案

与 Monad 不同,应用程序在产品和组合下是封闭的,因此不需要像“变压器”这样的特殊类别的东西。这是一个小图书馆:

data (*) f g x = P (f x) (g x)     deriving Functor
data C f g x = C (f (g x)) deriving Functor

instance (Applicative f, Applicative g) => Applicative (f * g) where
pure a = P (pure a) (pure a)
P ff gf <*> P fx gx = P (ff <*> fx) (gf <*> gx)

instance (Applicative f, Applicative g) => Applicative (C f g) where
pure = C . pure . pure
C fgf <*> C fgx = C (liftA2 (<*>) fgf fgx)

此外,所有的 monad 都是 Applicative,所以我们应该能够重用该代码。可悲的是,Applicative-Monad 子类型的缺乏迫使 monadic 代码比需要的更具排他性,因此禁止此类代码。如果所有这些库都要求提供 (Applicative m, Monad m),它可能会被纠正。约束,但他们没有。此外,考虑到您可能不得不写的频率
(MonadReader m, Monad m) => ...

Monad 父类(super class)约束很方便。但是,我不确定这是否完全必要。

关于haskell - 适用变压器类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25799124/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com