首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >新类型PrimMonad (ST s)栈的实现

新类型PrimMonad (ST s)栈的实现
EN

Stack Overflow用户
提问于 2018-11-30 22:47:51
回答 1查看 93关注 0票数 3

我正试图让renderTextxml-conduit那里得到ST monad的帮助。不幸的是,与renderBytes不同,它要求monad同时是PrimMonadMonadThrowIO满足这一点,但ST不满足。

代码语言:javascript
复制
renderText :: (PrimMonad m, MonadThrow m) => RenderSettings -> ConduitT Event Text m ()

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

instance PrimMonad m => PrimMonad (CatchT m) where type PrimState (CatchT m) = PrimState m primitive = lift . primitive

这是不健康的孤儿的例子。我试着把它包装成newtype,但被困在PrimMonad上了。

代码语言:javascript
复制
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

Update:为了记录在案,下面是基于@luqui的想法的答案。

代码语言:javascript
复制
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
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-30 23:39:31

您需要公开s参数:

代码语言:javascript
复制
newtype Render s a = Render { runRender :: MaybeT (ST s) a }

forall s. ST s a monad看起来很吸引人,但是它非常无用,因为(例如) newSTRef不能让它创建的ref转义。(尝试让STRef与您的单曲一起工作,以了解问题所在)

一旦公开了sPrimMonad实例就应该是简单明了的。

你也知道GeneralizedNewtypeDeriving的事,对吧?您不需要做所有这些工作来制作一个新类型的包装器。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53565931

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档