繁体   English   中英

2种以上的无形类型析取

[英]Shapeless type disjunction for more then 2 types

如何为无形中的 3 种或更多类型提供类型析取? 例子:

import shapeless._

object Tst extends App {

  sealed trait Base

  final case class A() extends Base
  final case class B() extends Base
  final case class C() extends Base
  final case class D() extends Base

  def AorB[T: (A |∨| B)#λ](t: T): Unit =
    t match {
      case _: A => println("A")
      case _: B => println("B")
    }
  AorB(A()) //Ok
  AorB(B()) //Ok

  def AorBorC[T: (A |∨| B |∨| C)#λ](t: T): Unit =
    t match {
      case _: A => println("A")
      case _: B => println("B")
      case _: C => println("C")
    }
  AorBorC(A()) //compile-error
  AorBorC(B()) //compile-error
  AorBorC(C()) //Ok
}

从 2 种类型的析取中可以看出,它完全可以正常工作。 但是对于 3 种类型的析取,它不能按预期工作。

编译错误是:

Error:(28, 10) Cannot prove that (Tst.A => Nothing) => Nothing <:< Object{type λ[X] = (X => Nothing) => Nothing <:< Tst.A => Nothing with Tst.B => Nothing => Nothing} => Nothing with Tst.C => Nothing => Nothing.
  AorBorC(A())

Error:(29, 10) Cannot prove that (Tst.B => Nothing) => Nothing <:< Object{type λ[X] = (X => Nothing) => Nothing <:< Tst.A => Nothing with Tst.B => Nothing => Nothing} => Nothing with Tst.C => Nothing => Nothing.
  AorBorC(B())

shapeless.|∨| 不适用于 2 种以上的类型。

http://milessabin.com/blog/2011/06/09/scala-union-types-curry-howard/

对于超过 2 种类型的编码变得更加复杂。

一种编码用于 2、4、8... 类型

type ¬¬¬¬[T] = ¬¬[¬¬[T]]
type |∨∨|[T, U] = {
  type λ[X] = ¬¬¬¬[X] <:< (T ∨ U)
}

def AorBorC[T: ((A ∨ B) |∨∨| (C ∨ C))#λ](t: T): Unit =
  t match {
    case _: A => println("A")
    case _: B => println("B")
    case _: C => println("C")
  }

AorBorC(A()) //Ok
AorBorC(B()) //Ok
AorBorC(C()) //Ok

另一个是任意数量的类型

trait Disj[T] {
  type or[S] = Disj[T with ¬[S]]
  type apply = ¬[T]
}

type ∨∨∨[T1, T2, T3] = Disj[¬[T1]]#or[T2]#or[T3]#apply

type |∨∨∨|[T1, T2, T3] = {
  type λ[X] = ¬¬[X] <:< ∨∨∨[T1, T2, T3]
}

def AorBorC[T: |∨∨∨|[A, B, C]#λ](t: T): Unit =
  t match {
    case _: A => println("A")
    case _: B => println("B")
    case _: C => println("C")
  }

AorBorC(A()) //Ok
AorBorC(B()) //Ok
AorBorC(C()) //Ok

如何定义“类型析取”(联合类型)?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM