Skip to content

Commit

Permalink
chore: prepare for the restrictions on match types in SIP-56 (close #12)
Browse files Browse the repository at this point in the history
Nested "type test extractors" like `IsSingleton` are not allowed
in the match types of SIP-56. Some of them were redundant and were
removed. The others were turned in explicit inner match types.
  • Loading branch information
sjrd authored and chuwy committed Mar 31, 2024
1 parent f38117f commit 3ca9457
Showing 1 changed file with 17 additions and 18 deletions.
35 changes: 17 additions & 18 deletions core/src/main/scala/skunk/tables/internal/typeops.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,17 @@ inline def findT[C <: Tuple, Label <: Singleton]: Find[C, Label] =
/** Pick only `TypedColumns` with certain labels */
type Pick[Columns <: Tuple, Labels <: Tuple] <: Tuple =
Labels match
case EmptyTuple => EmptyTuple
case IsSingleton[h] *: t => Find[Columns, h] *: Pick[Columns, t]

inline def pickT[C <: Tuple, Labels <: Tuple]: Pick[C, Labels] =
inline erasedValue[Labels] match
case _: EmptyTuple => EmptyTuple
case _: (IsSingleton[h] *: t) => findT[C, h] *: pickT[C, t]
case EmptyTuple =>
EmptyTuple
case h *: t =>
h match
case Singleton => Find[Columns, h & Singleton] *: Pick[Columns, t]

type Reify[C <: Tuple] <: Tuple =
C match
case EmptyTuple =>
EmptyTuple
case TypedColumn[IsSingleton[n], a, t, c] *: tail =>
case TypedColumn[n, a, t, c] *: tail =>
TypedColumn[n, a, t, c] *: Reify[tail]

// WARNING: it doesn't work if there's a type with given instance not
Expand All @@ -107,22 +105,22 @@ inline def reifyT[C <: Tuple]: Reify[C] =
inline erasedValue[C] match
case _: EmptyTuple =>
EmptyTuple
case _: (TypedColumn[IsSingleton[n], a, t, c] *: tail) =>
case _: (TypedColumn[n, a, t, c] *: tail) =>
TypedColumn[n, a, t, c](constValue[n], summonInline[IsColumn[a]]) *: reifyT[tail]

type ReifyN[C <: NonEmptyTuple] <: NonEmptyTuple =
C match
case TypedColumn[IsSingleton[n], a, t, c] *: EmptyTuple =>
case TypedColumn[n, a, t, c] *: EmptyTuple =>
TypedColumn[n, a, t, c] *: EmptyTuple
case TypedColumn[IsSingleton[n], a, t, c] *: h2 *: tail =>
case TypedColumn[n, a, t, c] *: h2 *: tail =>
TypedColumn[n, a, t, c] *: ReifyN[h2 *: tail]

/** Reify a homogenous tuple of `TypedColumn` */
inline def reifyNT[C <: NonEmptyTuple]: ReifyN[C] =
inline erasedValue[C] match
case _: (TypedColumn[IsSingleton[n], a, t, c] *: EmptyTuple) =>
case _: (TypedColumn[n, a, t, c] *: EmptyTuple) =>
TypedColumn[n, a, t, c](constValue[n], summonInline[IsColumn[a]]) *: EmptyTuple
case _: (TypedColumn[IsSingleton[n], a, t, c] *: h2 *: tail) =>
case _: (TypedColumn[n, a, t, c] *: h2 *: tail) =>
TypedColumn[n, a, t, c](constValue[n], summonInline[IsColumn[a]]) *: reifyNT[h2 *: tail]

type GetNames[C <: Tuple] <: Tuple =
Expand All @@ -141,8 +139,12 @@ inline def getNamesT[C <: Tuple]: GetNames[C] =

type GetInNames[I <: NonEmptyTuple] <: NonEmptyTuple =
I match
case TypedColumn.In[IsSingleton[n], ?, ?] *: EmptyTuple => n *: EmptyTuple
case TypedColumn.In[IsSingleton[n], ?, ?] *: t => n *: GetInNames[t]
case TypedColumn.In[n, ?, ?] *: EmptyTuple =>
n match
case Singleton => n *: EmptyTuple
case TypedColumn.In[n, ?, ?] *: t =>
n match
case Singleton => n *: GetInNames[t]

/** Match type to transform `(a, b, c, d)` of `TypedColumn.In` into `(((a, b), c), d)` (or `a ~ b ~
* c ~ d`)
Expand All @@ -159,9 +161,6 @@ type TwiddleInGo[I <: Tuple, A <: Tuple] =

// Generic operations

/** Type-level unapply, checking if `T` is a singleton */
type IsSingleton[T <: Singleton] = T

/** If `A` in tuple `T` - return `True` branch, otherwise `False` branch */
type IfIn[T <: Tuple, A, True, False] <: True | False = T match
case EmptyTuple => False
Expand Down

0 comments on commit 3ca9457

Please sign in to comment.