Skip to content

Commit

Permalink
Add ValueWithSchema
Browse files Browse the repository at this point in the history
  • Loading branch information
Primetalk committed Feb 2, 2025
1 parent 987d09a commit b9f2590
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,3 @@ package ru.primetalk.typed.ontology.typeclass.schema
/** @tparam C is a column that could be part of RecordSchema. */
trait Column[C]:
type Name <: String
// def name: Name

object Column:
inline def infer[Col: ValueOf]: Col =
valueOf[Col]

// inline def nameOf[C](using col: Column[C]): col.Name =
// col.name

// type NameOf[C] <: String = C match
// case {type Name <: String} => c#Name
// case _ => Nothing
type Columns[Schema <: Tuple] = Tuple.Map[Schema, Column]
// type ColumnNames[Schema <: Tuple] = Tuple.Map[Tuple.Map[Schema, Column], NameOf]

inline def columnNames[Schema <: Tuple](using columns: Columns[Schema]): columns.type =
columns
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ import scala.annotation.implicitNotFound
@FunctionalInterface
@implicitNotFound(msg = "Cannot obtain ${Column} of type ${ColumnValue} from ${Value}")
trait Getter[Column, ColumnValue, Value]:
def apply(rtc: Value): ColumnValue
def apply(rtc: Value): ValueWithSchema[Column, ColumnValue]
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package ru.primetalk.typed.ontology.typeclass.schema

import scala.compiletime.summonAll
/** T is a Tuple that represents a RecordSchema. */

/**
* This type class provides evidence that T represents a schema made of columns.
*
* @tparam T is a Tuple that represents a RecordSchema.
*/
trait RecordSchema[T <: Tuple]:
def columns: T

Expand All @@ -16,6 +21,7 @@ object RecordSchema:
given emptySchema: RecordSchema[EmptyTuple] =
EmptyRecordSchema


given nonEmptySchema[H: Column: ValueOf, T <: Tuple: RecordSchema]: RecordSchema[H *: T] =
new:
def columns: H *: T = valueOf[H] *: summon[RecordSchema[T]].columns
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import scala.NamedTupleDecomposition.*
/** Type-level annotation of a Tuple with it's RecordSchema.
* Elements are connected via Column[T], SchemaValueType[C].
*/
opaque type RecordTupleValue[R <: Tuple, +V <: Tuple] >: V = V
type RecordTupleValue[R <: Tuple, +V <: Tuple] = ValueWithSchema[R, V]

/** Instance of this type-class only exists when there are corresponding Column[T], SchemaValueType[C]. */
@implicitNotFound(msg = "Cannot prove that $V is a valid primitive value of schema $R.")
Expand All @@ -32,10 +32,10 @@ object RecordTupleValue:
inline def toNamedTuple[Names <: Tuple](using columnsNames: ColumnsNames[R, Names]): NamedTuple[Names, V] =
v.asInstanceOf[NamedTuple[Names, V]]

inline def prepend[H, HV](vh: HV)(using SchemaValueType[H, HV]): RecordTupleValue[H *: R, HV *: V] =
vh *: v.toTuple
inline def prepend[H, HV](vh: ValueWithSchema[H, HV]): RecordTupleValue[H *: R, HV *: V] =
vh.value *: v.toTuple

inline def get[Column, ColumnValue](column: Column)(using svt: SchemaValueType[Column, ColumnValue])(using getter: Getter[Column, ColumnValue, RecordTupleValue[R, V]]): ColumnValue =
inline def get[Column, ColumnValue](column: Column)(using svt: SchemaValueType[Column, ColumnValue])(using getter: Getter[Column, ColumnValue, RecordTupleValue[R, V]]): ValueWithSchema[Column, ColumnValue] =
getter(v)

inline def project[Dest <: Tuple, DestV <: Tuple](dest: Dest)(using proj: Projector[R, V, Dest, DestV]): RecordTupleValue[Dest, DestV] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package ru.primetalk.typed.ontology.typeclass.schema

import scala.language.experimental.namedTuples

/**
* Evidence that V is the underlying tuple for schema R.
*/
type RecordValueType[R <: Tuple, V <: Tuple] = SchemaValueType[R, RecordTupleValue[R, V]]

//object RecordValueType:
// type Aux[R <: Tuple, V <: Tuple] = RecordValueType[R] {type Value = V}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ object SchemaValueType:
type Value
val svt: SchemaValueType[SchemaOrColumn, Value]

class AuxImpl[SchemaOrColumn, V](val svt: SchemaValueType[SchemaOrColumn, V]) extends Aux[SchemaOrColumn]:
final class AuxImpl[SchemaOrColumn, V](val svt: SchemaValueType[SchemaOrColumn, V]) extends Aux[SchemaOrColumn]:
type Value = V

inline given [SchemaOrColumn, V](using SchemaValueType[SchemaOrColumn, V]): Aux[SchemaOrColumn] =
new AuxImpl[SchemaOrColumn, V](summon)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package ru.primetalk.typed.ontology.typeclass.schema

/**
* Annotation of value with schema. Could be used with records (tuples) or with plain values.
*/
opaque type ValueWithSchema[Schema, +Value] >: Value = Value

object ValueWithSchema:

private class IdentityConversion[A] extends Conversion[A, A]:
def apply(x: A): A = x

inline given valueToValueWithSchema[Schema, Value](using ev: SchemaValueType[Schema, Value]): Conversion[Value, ValueWithSchema[Schema, Value]] =
new IdentityConversion[ValueWithSchema[Schema, Value]]

extension [Schema, Value](vws: ValueWithSchema[Schema, Value])
def value: Value = vws

end ValueWithSchema

0 comments on commit b9f2590

Please sign in to comment.