本文介绍了使类型签名独立于特定的monad变量堆栈(Scala)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 通过将Haskell函数转换为Scala来学习Scala。我有一个包含StateMonad的monad变量堆栈 类型TI a = ... 使用这个monad变量堆栈的一个函数是: fresh :: TI Int fresh = do n 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中重写类型签名,使其仅取决于状态monad,而不取决于整个monad变量堆栈? MonadState 类型的类,尽管Scala类型推断的局限性意味着它不太优雅。例如,您可以编写以下内容: import scalaz._,Scalaz._ def新鲜[F [_,_]](隐式m:MonadState [F,Int]):F [Int,Int] = for { counter _ } yield counter 然后举例如下: scala>新鲜[State] res6:scalaz.State [Int,Int] = scalaz.IndexedStateT$$anon$10@6517b62 scala>类型OptionState [s,a] = StateT [Option,s,a] 定义的类型别名OptionState scala>新鲜[OptionState] res7:OptionState [Int,Int] = scalaz.IndexedStateT$$anon$10@43740ba6 请注意, MonadState 的第一个类型参数需要对状态和值都有漏洞,因此您需要调整 TI 如果您想使用此方法 - 新鲜[TI] 不会按原样工作。 I'm learning Scala by translating a Haskell function to Scala. I have a monad transformer stack containing the StateMonad type TI a = ... One function using this monad transformer stack is:fresh :: TI Intfresh = do n <- get put (n + 1) return nSince this function only depends on the State monad I may also change the type to:fresh :: (MonadState Int m) => m IntHow does this translate to Scala? In Scala, I use a monad transformer stack composing the state and the identity monad:type TI[A] = StateT[Id, scala.Int, A]The fresh function in Scala looks like this: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? 解决方案 Scalaz also provides a MonadState type class, although the limitations of Scala's type inference means it's much less elegant. 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 counterAnd then for example the following:scala> fresh[State]res6: scalaz.State[Int,Int] = scalaz.IndexedStateT$$anon$10@6517b62scala> type OptionState[s, a] = StateT[Option, s, a]defined type alias OptionStatescala> fresh[OptionState]res7: OptionState[Int,Int] = scalaz.IndexedStateT$$anon$10@43740ba6Note 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. 这篇关于使类型签名独立于特定的monad变量堆栈(Scala)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-31 16:30