传递性,或如何链接Scala中的一般隐含性

问题描述 投票:1回答:1

我正在尝试扩展Miles Sabin在这篇出色的文章中描述的功能:Unboxed Union Types以支持n一元类型的并集,例如:]]

def if[T](t: T)(implicit ev: T <<: (Int | String | Symbol | Double)): String = ???

我修改了Sabin的代码,并编写了自己的<:<运算符版本,如下所示。

object UnboxedTypeUnion extends TypeUnion {

  def is[T](t: T)(implicit ev: T <<: (Int | String | Double | Symbol)) =
    t match {
      case _: Int    => "int"
      case _: String => "string"
      case _: Double => "double"
      case _: Symbol => "symbol"
    }

  // Does not compile
  val x = implicitly[Int <<: (Int | String | Double)]
  val y = implicitly[Int <<: Not[Not[Not[Not[Int]]]]]

}

trait TypeUnion {
  type Not[A] = A => Nothing
  type |[A, B] = Not[Not[A] with Not[B]]

  sealed abstract class <<:[-A, +B] extends (A => B)

  object <<: {
    val singleton = new <<:[Any, Any] { override def apply(v1: Any): Any = v1 }

    implicit def instance[A]: A <<: A = singleton.asInstanceOf[A <<: A]
    implicit def negation[A]: A <<: Not[Not[A]] = singleton.asInstanceOf[A <<: Not[Not[A]]]
    implicit def transitivity[A, B, C](implicit ab: A <<: B, bc: B <<: C): A <<: C = singleton.asInstanceOf[A <<: C]
  }

}

潜在的问题是,每个附加的逻辑析取(OR)将结果的证据子类包装为新的双重否定,即

implicitly[Not[Not[Int]] <<: (Int | String)]
implicitly[Not[Not[Not[Not[Int]]]] <<: (Int | String | Double )]
implicitly[Not[Not[Not[Not[Not[Not[Int]]]]]] <<: (Int | String | Double | Symbol )]
// etc.

从理论上讲,我希望双重否定身份的定义与及物性的定义相结合,以使其能够起作用,但是我无法对其进行编译。有谁知道这是否可行,或者递归链接的泛型是否超出了Scala编译器的功能?

我正在尝试扩展Miles Sabin在这篇出色文章中描述的功能:Unboxed Union Types以支持n元类型的并集,例如:def if [T](t:T)(隐式ev:T << [

scala implicit union-types boolean-algebra propositional-calculus
1个回答
0
投票
尝试
© www.soinside.com 2019 - 2024. All rights reserved.