CodeLionX / actordb

Actor Database System Framework using Akka
MIT License
0 stars 2 forks source link

Restrict value type of Relations to (AnyVal ∨ String) #33

Open CodeLionX opened 6 years ago

CodeLionX commented 6 years ago

Issue

I suggest using type constraints to restrict the domain of possible value types (T) for the creation of ColumnDef[T]s to (AnyVal ∨ String). This would allow following types:

Problem Description

Currently, it is possible to create arbitrary complex types for usage in Relations. E.g.:

trait MyType
val col1 = ColumnDef[Array[Map[Int, Any]]]("")
val col2 = ColumnDef[Map[BigInt, MyType] => Seq[String] => (Int, Int)]("")

Supporting Information

Possible implementation for restricting the value type of relations via the factory method in the companion object of ColumnDef[T]:

object ColumnDef {
  type ¬[A] = A => Nothing // ~ type-negation
  type ∨[T, U] = ¬[¬[T] with ¬[U]] // ~ type-union
  type ¬¬[A] = ¬[¬[A]] // ~ type-double-negation to compensate for union-notation
  type |∨|[T, U] = { type λ[X] = ¬¬[X] <:< (T ∨ U) } // proof for union type

  def apply[T: (AnyVal |∨| String)#λ](name: String)(implicit ct: ClassTag[T]): ColumnDef[T] =
    new ColumnDef[T](name)(ct)
}

see Miles Sabin (2009): Unboxed union types in Scala via the Curry-Howard isomorphism

CodeLionX commented 6 years ago

What about dates, timestamps and so on?

srfc commented 6 years ago

What about dates, timestamps and so on?

I see two possible solutions for dates and times:

I personally prefer the first option.

CodeLionX commented 6 years ago

I try to avoid using the old java.util.Date-classes. In the sample application I used java.time.LocalDate or java.time.LocalDateTime, but we may adjust this to java.time.ZonedDateTime to be independent of the local server's timezone.

This will lead to a more complex context-bound as well:

object ColumnDef {
  type ¬[A] = A => Nothing // ~ type-negation
  type ¬¬[A] = ¬[¬[A]] // ~ type-double-negation to compensate for union-notation

  // recursive definition
  trait Disj[T] {
    type or[S] = Disj[T with ¬[S]]
    type apply[X] = ¬¬[X] <:< ¬[T]
  }
  // for convenience
  type |∨|[T] = { type or[S] = Disj[¬[T]]#or[S] }

  def apply[T: |∨|[AnyVal]#or[String]#or[ZonedDateTime]#apply](name: String)(implicit ct: ClassTag[T]): ColumnDef[T] =
    new ColumnDef[T](name)(ct)
}

This time I used a recursive definition of the union of two types.

CodeLionX commented 6 years ago

As of PR #102 the type-bound for cell types is explicitly set to Any in:

class ColumnDef[+T <: Any](...

It is also covariant to comply with our map-based implementation for Records. We now have to check if the suggested type-bounds are still applicable.