1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
// non-deterministic type errors, non-termination.
// seems to be due to inconsistent hashing/equality in SubTypePair
import scala.language.{existentials, implicitConversions}
import scala.annotation.unchecked.uncheckedVariance
trait Column[T]
// Turning this into a trait reduces (eliminates?) the likelihood of type errors (but not of non-termination)
abstract class Shape[Level <: ShapeLevel, -Mixed_, Unpacked_, Packed_]
trait ShapeLevel
trait NestedShapeLevel extends ShapeLevel
trait FlatShapeLevel extends NestedShapeLevel
trait ColumnsShapeLevel extends FlatShapeLevel
trait ProvenShape[U]
object ProvenShape {
implicit def proveShapeOf[T, U](v: T)(implicit sh: Shape[_ <: FlatShapeLevel, T, U, _]): ProvenShape[U] = ???
}
sealed abstract class HList {
type Self <: HList
type :: [E] = HCons[E, Self]
final def :: [E](elem: E): :: [E] = ???
}
final class HCons[+H, +T <: HList](val head: H, val tail: T) extends HList {
type Self = HCons[H @uncheckedVariance, T @uncheckedVariance]
}
final object HNil extends HList {
type Self = HNil.type
}
// Success is more likely when not using these aliases
object syntax {
type :: [+H, +T <: HList] = HCons[H, T]
type HNil = HNil.type
}
class HListBench {
import syntax._
implicit def columnShape[T, Level <: ShapeLevel]: Shape[Level, Column[T], T, Column[T]] = ???
implicit def provenShape[T, P](implicit shape: Shape[_ <: FlatShapeLevel, T, _, P]): Shape[FlatShapeLevel, ProvenShape[T], T, P] = ???
final class HListShape[Level <: ShapeLevel, M <: HList, U <: HList, P <: HList](val shapes: Seq[Shape[_ <: ShapeLevel, _, _, _]]) extends Shape[Level, M, U, P]
implicit def hnilShape[Level <: ShapeLevel]: HListBench.this.HListShape[Level,HNil.type,HNil.type,HNil.type] = new HListShape[Level, HNil.type, HNil.type, HNil.type](Nil)
implicit def hconsShape[Level <: ShapeLevel, M1, M2 <: HList, U1, U2 <: HList, P1, P2 <: HList]
(implicit s1: Shape[_ <: Level, M1, U1, P1], s2: HListShape[_ <: Level, M2, U2, P2]): HListBench.this.HListShape[Level,syntax.::[M1,M2],syntax.::[U1,U2],syntax.::[P1,P2]] =
new HListShape[Level, M1 :: M2, U1 :: U2, P1 :: P2](s1 +: s2.shapes)
trait A[T] {
def * : ProvenShape[T]
}
trait B extends A[
Int :: Int :: Int :: Int :: Int ::
Int :: Int :: Int :: Int :: Int ::
Int :: Int :: Int :: Int :: Int ::
Int :: Int :: Int :: Int :: Int ::
Int :: Int :: Int :: Int :: Int ::
Int :: Int :: HNil ] {
def c: Column[Int]
def * = c :: c :: c :: c :: c ::
c :: c :: c :: c :: c ::
c :: c :: c :: c :: c ::
c :: c :: c :: c :: c ::
c :: c :: c :: c :: c ::
c :: c :: HNil
}
}
|