gpt4 book ai didi

haskell - 为 newtype-d CatchT (ST) 堆栈实现 PrimMonad

转载 作者:行者123 更新时间:2023-12-02 16:48:10 24 4
gpt4 key购买 nike

我正在尝试使用 ST monad 从 xml-conduit 获取 renderText。不幸的是,与renderBytes不同,它要求monad同时是PrimMonadMonadThrowIO 满足这一点,但 ST 不满足。

renderText :: (PrimMonad m, MonadThrow m) => RenderSettings -> ConduitT Event Text m ()

通过定义 PrimMonad 实例,我设法让它与 CatchT (ST s) a 堆栈一起工作:

实例 PrimMonad m => PrimMonad (CatchT m) 其中
类型 PrimState (CatchT m) = PrimState m
原语=升力。原始

这是不健康的孤儿实例。我尝试将其包装成 newtype,但卡在 PrimMonad 上。

newtype Render a = Render { runRender :: forall s. MaybeT (ST s) a }

instance Functor Render where
fmap f (Render m) = Render (fmap f m)

instance Applicative Render where
pure a = Render (pure a)
(Render f) <*> (Render v) = Render (f <*> v)

instance Monad Render where
a >>= f = Render $ do
v <- runRender a
runRender (f v)

instance MonadThrow Render where
throwM _ = Render $ MaybeT $ pure Nothing

instance PrimMonad Render where
[???]

我如何为这个堆栈定义PrimMonad

更新:郑重声明,这是基于@luqui想法的答案。

newtype Render s a = Render { runRender :: MaybeT (ST s) a }

deriving instance Functor (Render s)
deriving instance Applicative (Render s)
deriving instance Monad (Render s)

instance MonadThrow (Render s) where
throwM _ = Render $ MaybeT $ pure Nothing

instance PrimMonad (Render s) where
type PrimState (Render s) = s
primitive f = Render $ lift $ primitive f

最佳答案

您需要公开 s 参数:

newtype Render s a = Render { runRender :: MaybeT (ST s) a }

A forall s。 ST 是一个 monad 看起来很吸引人,但它非常无用,因为(例如)newSTRef 不能让它创建的引用逃脱。 (尝试让 STRef 与您的 monad 一起工作以查看问题)

一旦公开 sPrimMonad 实例就应该很简单。

您还知道GeneralizedNewtypeDeriving , 正确的?您不必完成所有这些工作来制作新类型包装器。

关于haskell - 为 newtype-d CatchT (ST) 堆栈实现 PrimMonad,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53565931/

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