一系列类型的抽象

pon*_*ite 7 scala scalaz shapeless

假设我们有一个类型T[A,B],我们可以表达以下类型约束,让我们调用它HT:

满足的每一种类型都HT必须是形式的T[P1, P2] :: T[P2, P3] :: T[P3, P4] :: ... :: T[PN-1, PN] :: HNil

对于一些type x = P1 :: P2 :: ... :: PN :: HNil.

我试图在类型化的顺序处理管道上找到一个抽象.

Tra*_*own 6

执行此类操作最方便的方法通常是编写自己的类型类.这是一个快速工作草图:

import shapeless._

trait T[I, O] extends (I => O)

trait Pipeline[P <: HList] {
  type In
  type Out
  type Values <: HList
}

object Pipeline {
  type Aux[P <: HList, In0, Out0, Values0 <: HList] = Pipeline[P] {
    type In = In0; type Out = Out0; type Values = Values0
  }

  def apply[P <: HList](
    implicit pipeline: Pipeline[P]
  ): Aux[P, pipeline.In, pipeline.Out, pipeline.Values] = pipeline

  implicit def onePipeline[I, O]: Aux[T[I, O] :: HNil, I, O, I :: O :: HNil] =
    new Pipeline[T[I, O] :: HNil] {
      type In = I
      type Out = O
      type Values = I :: O :: HNil
    }

  implicit def longerPipeline[I, O, P <: HList, Out0, Values0 <: HList](
    implicit pipeline: Aux[P, O, Out0, Values0]
  ): Aux[T[I, O] :: P, I, Out0, I :: Values0] =
    new Pipeline[T[I, O] :: P] {
      type In = I
      type Out = Out0
      type Values = I :: Values0
    }
}
Run Code Online (Sandbox Code Playgroud)

然后(为了清晰起见重新格式化):

scala> Pipeline[T[String, Int] :: T[Int, Char] :: HNil]
res5: Pipeline[T[String, Int] :: T[Int, Char] :: HNil] {
  type In = String
  type Out = Char
  type Values = String :: Int :: Char :: HNil
} = Pipeline$$anon$2@38fd077c

scala> Pipeline[T[String, Int] :: T[Char, Char] :: HNil]
<console>:19: error: could not find implicit value for parameter
  pipeline: Pipeline[[T[String, Int] :: T[Char, Char] :: HNil]
              Pipeline[T[String, Int] :: T[Char, Char] :: HNil]
                      ^
Run Code Online (Sandbox Code Playgroud)

无效管道无法编译,对于有效管道,我们可以正确推断出端点和中间值.