结合StateT和国家monad [英] Combining StateT and State monads
问题描述
可以说我有一个函数
f :: State [Int] Int
$ c $
< :StateT [Int] IO Int
我想要使用 f
in g
并传递它们之间的状态。是否有库函数用于
StateT(return。runState f)
?或者一般情况下,给定一个monad转换器与相应的monad,是否有一个库函数呢?
,你要做的是将变换应用到变压器堆栈的内层。对于两个任意monad,类型签名可能如下所示:
fmapMT ::(MonadTrans t,Monad m1,Monad m2 )=> (m1 a - > m2 a) - > t m1 a - > t m2 a
基本上是一个更高级的 fmap
。事实上,将它与最终参数上的地图结合起来可能会更有意义:
fmapMT :: (MonadTrans t,Monad m1,Monad m2)=> (m1a→m2b)→> t m1 a - > t m2 b
很明显,在所有情况下这都是不可能的,尽管当源monad
class MonadT t => FMonadT t其中
tmap':: FunctorD m - > FunctorD n - > (a - > b)
- > (全部x,m x - > n x) - > t m a - > t n b
tmap ::(FMonadT t,Functor m,Functor n)=> (全部b。m b - > n b)
- > t m a - > tna
tmap = tmap'functor functor id
在 tmap'
, FunctorD
类型基本上是 fmap
的临时实现,而不是直接使用 Functor
实例。
另外,对于两个Functor类型的构造函数F和G,类型如(forall a。F a - > G a)
描述自然转换从F到G.还有可能是另一个变换器映射的实现想要在 category-extras
包中的某处找到,但我不确定monad变换器的类别理论版本是什么,所以我不知道它可能称为什么。
$ b 由于
tmap
只需要一个 Functor
实例其中任何 Monad
必须有)和自然转换,并且任何 Monad
都有一个从 identity monad提供的自然转换返回
,你想要的函数可以一般地写入 FMonadT
的任何实例为 tmap(return。 runIdentity)
- 假设basicmonad被定义为应用于 Identity
的变换器的同义词,无论如何,它通常是请注意,Monatron确实有一个 FMonadT
的实例。
为 StateT
。
Lets say I have a function
f :: State [Int] Int
and a function:
g :: StateT [Int] IO Int
I want to use f
in g
and pass the state between them. Is there a library function for
StateT (return . runState f)
? Or in general, given a monad transformer with a corresponding monad, is there a library function for it?
解决方案 In even more general, what you're trying to do is apply a transformation to an inner layer of a transformer stack. For two arbitrary monads, the type signature might look something like this:
fmapMT :: (MonadTrans t, Monad m1, Monad m2) => (m1 a -> m2 a) -> t m1 a -> t m2 a
Basically a higher-level fmap
. In fact, it would probably make even more sense to combine it with a map over the final parameter as well:
fmapMT :: (MonadTrans t, Monad m1, Monad m2) => (m1 a -> m2 b) -> t m1 a -> t m2 b
Clearly this isn't going to be possible in all cases, though when the "source" monad is Identity
it's likely to be easier, but I can imagine defining another type class for the places it does work. I don't think there's anything like this in the typical monad transformer libraries; however, some browsing on hackage turns up something very similar in the Monatron
package:
class MonadT t => FMonadT t where
tmap' :: FunctorD m -> FunctorD n -> (a -> b)
-> (forall x. m x -> n x) -> t m a -> t n b
tmap :: (FMonadT t, Functor m, Functor n) => (forall b. m b -> n b)
-> t m a -> t n a
tmap = tmap' functor functor id
In the signature for tmap'
, the FunctorD
types are basically ad-hoc implementations of fmap
instead of using Functor
instances directly.
Also, for two Functor-like type constructors F and G, a function with a type like (forall a. F a -> G a)
describes a natural transformation from F to G. There's quite possibly another implementation of the transformer map that you want somewhere in the category-extras
package but I'm not sure what the category-theoretic version of a monad transformer would be so I don't know what it might be called.
Since tmap
requires only a Functor
instance (which any Monad
must have) and a natural transformation, and any Monad
has a natural transformation from the Identity
monad provided by return
, the function you want can be written generically for any instance of FMonadT
as tmap (return . runIdentity)
--assuming the "basic" monad is defined as a synonym for the transformer applied to Identity
, at any rate, which is generally the case with transformer libraries.
Getting back to your specific example, note that Monatron does indeed have an instance of FMonadT
for StateT
.
这篇关于结合StateT和国家monad的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!