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

scala – 使用中间变量时,理解失败

发布时间:2020-12-16 18:52:06 所属栏目:安全 来源:网络整理
导读:Scastie version 有了这个基础结构: trait Pat[A]object Pat { def apply[A](elems: A*): Pat[A] = ???}implicit class PatOps[A](p: Pat[A]) { def ++ (that: Pat[A]): Pat[A] = ??? def bubble: Pat[Pat[A]] = ??? def grouped(size: Pat[Int]): Pat[Pat[
Scastie version

有了这个基础结构:

trait Pat[A]
object Pat {
  def apply[A](elems: A*): Pat[A] = ???
}

implicit class PatOps[A](p: Pat[A]) {
  def ++ (that: Pat[A]): Pat[A] = ???

  def bubble: Pat[Pat[A]] = ???

  def grouped(size: Pat[Int]): Pat[Pat[A]] = ???
}

implicit class PatPatOps[A](p: Pat[Pat[A]]) {
  def map[B](f: Pat[A] => Pat[B]): Pat[Pat[B]] = ???

  def flatMap[B](f: Pat[A] => Pat[B]): Pat[B] = ???

  def flatten: Pat[A] = ???
}

可以写下以下的理解:

trait Test1 {
  val lPat = Pat(1,2,3)
  val xs = for {
    len     <- lPat.bubble
    cantus  <- Pat(4,40,3).grouped(len)
  } yield {
    cantus ++ Pat(-1)
  }
  xs.flatten
}

但是这个使用中间变量失败了:

trait Test2 {
  val lPat = Pat(1,3)
  val xs = for {
    len     <- lPat.bubble  // XXX
    brown = Pat(4,3)
    cantus  <- brown.grouped(len)
  } yield {
    cantus ++ Pat(-1)
  }
  xs.flatten
}

标记为XXX的行的错误是:

06003

Scala是2.12.4

解决方法

当您使用过度限制的签名映射定义映射时会发生这种情况[B](f:Pat [A] => Pat [B]).回想一下,通常,它应该接受具有任意结果类型B的函数,也就是说,它应该是这样的:

map[B](f: A => B): <stuff>

现在,你的理解与中间辅助变量棕色

val xs = for {
    len     <- lPat.bubble
    brown = Pat(4,3)
    cantus  <- brown.grouped(len)
  } yield {
    cantus ++ Pat(-1)
  }

用地图重写成

val xs = lPat.bubble.map(((len) => {
    val brown = Pat(4,3);
    scala.Tuple2(len,brown)
  })).flatMap(((x$1) => x$1: @scala.unchecked match {
    case scala.Tuple2((len @ _),(brown @ _)) => 
      brown.
        grouped(len).
        map(((cantus) => cantus.$plus$plus(Pat(-1))))
  }))

如the documentation或in my overly detailed answer here所述.

注意隐式生成的映射的返回类型现在是如何(Pat [A],Pat [Int])(元组的类型(len,brown)),并且与模式Pat [B]不匹配你的声明.

我没有看到任何变通方法.尽你所能避免将地图定义为地图[B](f:Pat [A] => Pat [B]),否则它会表现得太奇怪了.避免破坏地图的功能.如果您的Pat [X]无法映射f:X =>对于任意X和Y,Y为Pat [Y],然后不要将其称为map.

编辑:总有一个解决方法……

你可以做的一件事是介绍一些隐式提供的CanPatFrom:

trait CanPatFrom[X,A] extends (X => Pat[A])

然后

...
def map[X,B](f: Pat[A] => X)(implicit cpf: CanPatFrom[X,B]) = {
  val pb: Pat[B] = cpf(f(...))
  /* do your stuff here with `Pat[B]` instead of 
   * generic `X`
   */
  ...
}

假设你的Pat带有某种笛卡尔 – 幺半群结构,你可以定义

> CanPatFrom [Pat [A],Pat [A]],
> CanPatFrom [(Pat [A],Pat [B]),Pat [(A,B)]],Pat [B],Pat [C]),B,C)]],
> ……

从而获得至少可以应对返回类型是元组的情况的映射.

(编辑:李大同)

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

    推荐文章
      热点阅读