Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
CodeLionX opened this issue May 11, 2018 · 4 comments
Open

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

CodeLionX opened this issue May 11, 2018 · 4 comments
Labels
Nice-To-Have question Further information is requested

Comments

@CodeLionX
Copy link
Owner

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:

  • AnyVal, Byte, Short, Int, Long, Float, Double, Char, Boolean
  • and String (as String -> CharSequence -> Object -> Any, we need to include it separately)
  • value classes (T extends AnyVal)

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] <:< (TU) } // 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 CodeLionX added question Further information is requested Nice-To-Have labels May 11, 2018
@CodeLionX
Copy link
Owner Author

What about dates, timestamps and so on?

@srfc
Copy link
Collaborator

srfc commented May 19, 2018

What about dates, timestamps and so on?

I see two possible solutions for dates and times:

  • allow java.sql.Date as a ColumnDef type. The caveat is that java.sql.Date is subclass of java.util.Date and then immediately Object
  • use Strings encoding a datetime and parse these strings any time they're used.

I personally prefer the first option.

@CodeLionX
Copy link
Owner Author

CodeLionX commented May 19, 2018

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
Copy link
Owner Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Nice-To-Have question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants