[英]Making the type signature independent of a specific monad transformer stack (Scala)
I'm learning Scala by translating a Haskell function to Scala. 我正在通过将Haskell函数转换为Scala来学习Scala。 I have a monad transformer stack containing the StateMonad
我有一个包含StateMonad的monad变换器堆栈
type TI a = ...
One function using this monad transformer stack is: 使用此monad变换器堆栈的一个功能是:
fresh :: TI Int
fresh = do n <- get
put (n + 1)
return n
Since this function only depends on the State monad I may also change the type to: 由于此函数仅依赖于状态monad,因此我也可以将类型更改为:
fresh :: (MonadState Int m) => m Int
How does this translate to Scala? 这如何转化为Scala? In Scala, I use a monad transformer stack composing the state and the identity monad:
在Scala中,我使用构成状态和身份monad的monad变换器堆栈:
type TI[A] = StateT[Id, scala.Int, A]
The fresh function in Scala looks like this: Scala中的新功能如下所示:
def fresh:TI[Ty] = for {
counter <- get[scala.Int]
_ <- put[scala.Int] (counter + 1)
} yield {
TyVar(counter)
}
How do I rewrite the type signature in Scala in such a way that in only depends on the State monad and not on the whole monad transformer stack? 如何以这样的方式重写Scala中的类型签名:仅依赖于State monad而不是整个monad转换器堆栈?
Scalaz also provides a MonadState
type class, although the limitations of Scala's type inference means it's much less elegant. Scalaz还提供了一个
MonadState
类型类,虽然Scala类型推断的局限性意味着它不那么优雅。 You could write the following, for example: 您可以编写以下内容,例如:
import scalaz._, Scalaz._
def fresh[F[_, _]](implicit m: MonadState[F, Int]): F[Int, Int] = for {
counter <- m.get
_ <- m.put(counter + 1)
} yield counter
And then for example the following: 然后举例如下:
scala> fresh[State]
res6: scalaz.State[Int,Int] = scalaz.IndexedStateT$$anon$10@6517b62
scala> type OptionState[s, a] = StateT[Option, s, a]
defined type alias OptionState
scala> fresh[OptionState]
res7: OptionState[Int,Int] = scalaz.IndexedStateT$$anon$10@43740ba6
Note that the first type parameter for MonadState
needs to have holes for both the state and the value, so you'll need to adjust your TI
if you want to use this approach— fresh[TI]
won't work as is. 请注意,
MonadState
的第一个类型参数需要为状态和值都设置漏洞,因此如果要使用此方法,则需要调整TI
fresh[TI]
将无法正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.