Scalahansolo
Scalahansolo

Reputation: 3065

Enforcing polymorphic parameters to be of same type

In the method below, I was hoping to set up the type of the function to enforce that from and to are the same type of LexicalDate. I.e. they must both be Day or both must be Hour.

Currently, from and to can be passed as different types of LexicalDate.

Can from and to be forced at the compile level to always be the same type of LexicalDate?

sealed trait LexicalDate 
case object Day extends LexicalDate
case object Hour extends LexicalDate
def queryDate[Date <: LexicalDate](
    id: Long,
    from: Date,
    to: Date
  )

Upvotes: 1

Views: 84

Answers (1)

dkim
dkim

Reputation: 3970

What you are looking for is the generalized type constraint =:=, which requires that a compiler should be able to prove that two types are equal. For your case, =:= can be used as follows (in particular, note the implicit parameter list of the queryDate method):

scala> def queryDate[A <: LexicalDate, B <: LexicalDate](id: Long, from: A, to: B)(implicit ev: A =:= B) { }
queryDate: [A <: LexicalDate, B <: LexicalDate](id: Long, from: A, to: B)(implicit ev: A =:= B)Unit

scala> queryDate(10, Day, Day)

scala> queryDate(10, Hour, Hour)

scala> queryDate(10, Day, Hour)
<console>:15: error: Cannot prove that Day.type =:= Hour.type.
       queryDate(10, Day, Hour)
                ^

scala> queryDate(10, Hour, Day)
<console>:15: error: Cannot prove that Hour.type =:= Day.type.
       queryDate(10, Hour, Day)
                ^

Refer to the following links for the general description of generalized type constraints:

Upvotes: 3

Related Questions