Я пытаюсь заставить renderText
из xml-conduit
работать с ST
монадой.К сожалению, в отличие от renderBytes
, требуется, чтобы монада была и PrimMonad
, и MonadThrow
.IO
удовлетворяет этому, но ST
нет.
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
Это нездоровая сирота.Я попытался обернуть его в новый тип, но застрял на 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