繁体   English   中英

使类型签名独立于特定的monad变换器堆栈(Scala)

[英]Making the type signature independent of a specific monad transformer stack (Scala)

我正在通过将Haskell函数转换为Scala来学习Scala。 我有一个包含StateMonad的monad变换器堆栈

type TI a = ... 

使用此monad变换器堆栈的一个功能是:

fresh :: TI Int
fresh = do n <- get
           put (n + 1)
           return n

由于此函数仅依赖于状态monad,因此我也可以将类型更改为:

fresh :: (MonadState Int m) => m Int

这如何转化为Scala? 在Scala中,我使用构成状态和身份monad的monad变换器堆栈:

type TI[A] = StateT[Id, scala.Int, A]

Scala中的新功能如下所示:

def fresh:TI[Ty] = for {
  counter <- get[scala.Int]
  _ <- put[scala.Int] (counter + 1)
} yield {
  TyVar(counter)
}

如何以这样的方式重写Scala中的类型签名:仅依赖于State monad而不是整个monad转换器堆栈?

Scalaz还提供了一个MonadState类型类,虽然Scala类型推断的局限性意味着它不那么优雅。 您可以编写以下内容,例如:

import scalaz._, Scalaz._

def fresh[F[_, _]](implicit m: MonadState[F, Int]): F[Int, Int] = for {
  counter <- m.get
  _       <- m.put(counter + 1)
} yield counter

然后举例如下:

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

请注意, MonadState的第一个类型参数需要为状态和值都设置漏洞,因此如果要使用此方法,则需要调整TI fresh[TI]将无法正常工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM