结合StateT和国家monad [英] Combining StateT and State monads

查看:134
本文介绍了结合StateT和国家monad的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可以说我有一个函数

  f :: State [Int] Int 




< :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 Identity 可能会更容易一些,但我可以想象为它工作的地方定义另一个类型类。我不认为典型的monad变压器库中有这样的东西;然而,一些在hackage上浏览的东西变得非常相似 Monatron 软件包中:3aFMonadTrel =nofollow>:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆