加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Monad Transformer在Scala中堆叠

发布时间:2020-12-16 18:20:34 所属栏目:安全 来源:网络整理
导读:我正在学习 Scala中的monad变换器,但是遇到了一个我发现到目前为止无法解决的问题.在我的monad变换器堆栈中,我组成了Either和State monad.但是,我无法调用属于两个monad之一的函数: import scalaz._import Scalaz._object Minimal { type Inner[A] = Either
我正在学习 Scala中的monad变换器,但是遇到了一个我发现到目前为止无法解决的问题.在我的monad变换器堆栈中,我组成了Either和State monad.但是,我无法调用属于两个monad之一的函数:

import scalaz._
import Scalaz._

object Minimal {
  type Inner[A] = EitherT[Id,String,A]
  type Outer[F[+_],A] = StateT[F,Int,A]
  type Stack[A] = Outer[Inner,A]

  def foo:Stack[Int] = for {
    n <- get[Int]
  } yield {
    2 * n
  }

  def main(args: Array[String]): Unit = {
    val x = foo.eval(8)
    println(x)
  }
}

失败,出现以下错误消息:

[error] Minimal.scala:10: type mismatch;
[error]  found   : scalaz.IndexedStateT[scalaz.Id.Id,Int]
[error]  required: Minimal.Stack[Int]
[error]     (which expands to)  scalaz.IndexedStateT[Minimal.Inner,Int]
[error]     n <- get[Int]

如果我将monad变换器堆栈更改为:

type Stack[A] = State[Int,A]

该程序编译和运行没有问题.有谁知道我在这里做错了什么?

解决方法

方法调用get [Int]返回一个IndexedStateT [Id,Int].您的Stack [Int]扩展为IndexedStateT [Inner,Int],其中Inner是EitherT [Id,A].这有点难以理解,所以我会简化你的例子.

我们使用Option创建一个StateT,而不是Inner类型别名.

type Stack[A] = StateT[Option,A]

get [Int]的赋值仍然会失败.

val x:Stack[Int] = get[Int]
//type mismatch; 
//  found : scalaz.State[Int,Int]
//    (which expands to) scalaz.IndexedStateT[scalaz.Id.Id,Int]
//  required: Minimal.Stack[Int] 
//    (which expands to) scalaz.IndexedStateT[Option,Int]

为了解决这个问题,我们需要将变压器提升到一个选项:

val x:Stack[Int] = get[Int].lift[Option]

如果您将其转换为示例代码,则需要将State提升为内部.请注意,您还需要将Inner的定义更改为协变:

type Inner[+A] = EitherT[Id,A]
type Stack[A] = StateT[Inner,A]

val x:Stack[Int] = get[Int].lift[Inner]

为了能够在不手动提升的情况下编写此内容,您可以引入隐式转换.完整的例子:

type Inner[+A] = EitherT[Id,A]
type Outer[F[+_],A]
type Stack[A] = Outer[Inner,A]

implicit def liftToStack[A](x:Outer[Id,A]):Stack[A] = x.lift[Inner]

def foo: Stack[Int] = for {
  n <- get[Int]
} yield {
  2 * n
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读