【问题标题】:Pattern matching dependent types - how to avoid asInstanceOf?模式匹配依赖类型 - 如何避免 asInstanceOf?
【发布时间】:2015-06-19 09:59:52
【问题描述】:

我对如何在不作弊和使用asInstanceOf 的情况下完成以下任务持空白。

假设我有一些任意密封类型的对象,每个对象都有自己的类型成员。

  sealed trait Part { type A }
  case object P1 extends Part { override type A = String }
  case object P2 extends Part { override type A = Int }

现在说我将一个 P 和一个 P.A 值捆绑在一起......

  trait PartAndA {
    val p: Part
    val a: p.A
  }

  object PartAndA {
    type Aux[P <: Part] = PartAndA {val p: P}

    def apply(_p: Part)(_a: _p.A): Aux[_p.type] =
      new PartAndA {
        override val p: _p.type = _p
        override val a          = _a
      }
  }

如何在没有手动强制转换的情况下安全地完成以下任务?

  def fold[A](pa: PartAndA)(p1: PartAndA.Aux[P1.type] => A,
                            p2: PartAndA.Aux[P2.type] => A): A =
    pa.p match {
      case P1 => p1(pa.asInstanceOf[PartAndA.Aux[P1.type]])
      case P2 => p2(pa.asInstanceOf[PartAndA.Aux[P2.type]])
    }

【问题讨论】:

    标签: scala scala-2.11


    【解决方案1】:

    我认为您的问题与jvm type erasure 有关。没有它,您的问题可以简化为:

    sealed trait Part { type A }
    case class P1() extends Part { override type A = String }
    case class P2() extends Part { override type A = Int }
    
    trait PartAndA[P <: Part] {
      val p: P
      val a: p.A
    }
    
    object PartAndA {
      type Aux[P <: Part] = PartAndA[P]
    
      def apply(_p: Part)(_a: _p.A): PartAndA[_p.type] =
        new PartAndA[_p.type] {
          override val p: _p.type = _p
          override val a          = _a
        }
    }
    
    def fold[A, T: ClassTag](pa: PartAndA[T])(p1: PartAndA[P1] => A,
                              p2: PartAndA[P2] => A): A =
      pa match {
        case s: PartAndA[P1]  => p1(pa) // here P1 is lost, err 
        case i: PartAndA[P2] => p2(pa) // here P2 is lost, err
      }
    

    据我所知,没有更短的(比你的或typeTags/classTags)jvm 类型擦除的解决方法。

    【讨论】:

    • 啊,是的,如果我在pa 上进行匹配,情况就是这样,但pa.p 是具体的,我们可以在没有擦除问题的情况下进行匹配。我只是不知道如何构造一个证明,如果我知道pa.p 类型,那么我就知道PartAndA.Aux 类型。
    猜你喜欢
    • 2020-08-27
    • 2016-05-17
    • 2014-12-08
    • 2020-04-06
    • 2020-01-30
    • 1970-01-01
    • 2011-10-14
    • 2020-10-24
    • 1970-01-01
    相关资源
    最近更新 更多