Type sequence abstraction

Assuming we have type T[A,B] , can we express the following type restriction, call it HT :

each type satisfying the HT condition must have the form T[P1, P2] :: T[P2, P3] :: T[P3, P4] :: ... :: T[PN-1, PN] :: HNil

for some type x = P1 :: P2 :: ... :: PN :: HNil .

I am trying to find an abstraction over a typed serial processing pipeline.

+7
scala scalaz shapeless
source share
1 answer

The most convenient way to do this is usually to write your own type. Here is a quick working sketch:

 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 } } 

And then (reformatted for clarity):

 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] ^ 

An invalid pipeline does not compile, and for a valid value, we get the correct conclusions for the endpoints and intermediate values.

+6
source share

All Articles