Skip to content

LMS-inspired test cases for higher-kinded types #94

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

Closed
namin opened this issue Mar 25, 2014 · 1 comment
Closed

LMS-inspired test cases for higher-kinded types #94

namin opened this issue Mar 25, 2014 · 1 comment
Assignees

Comments

@namin
Copy link
Contributor

namin commented Mar 25, 2014

This compiles without error:

import scala.language.higherKinds

trait Base {
  type Rep[T]
}

trait BaseExp extends Base {
  type Rep[T] = Exp[T]
  case class Exp[T](v: T)
}

The next trait compiles with an error (which feels inadequate and the source location is lost during reporting):

trait BaseStr extends Base {
  type Rep[T] = String
}
error: right-hand side of parameterized alias type must refer to a class
one error found

The next trait compiles with the same error (though I guess it is by design here and the source location is preserved):

trait BaseDirect extends Base {
  type Rep[T] = T
}
error: right-hand side of parameterized alias type must refer to a class
  type Rep[T] = T
             ^
one error found

All these traits compile fine with Scala 2.10.3.

@namin
Copy link
Contributor Author

namin commented Mar 25, 2014

More higher-kinded type examples that compile with Scala 2.10.3, but not Dotty.

import scala.language.higherKinds

trait Test {
  trait Monad[X] {
    def x: X
  }
  sealed abstract class Either[A,B]
  case class Left[A,B](x: A) extends Either[A,B] with Monad[A]
  case class Right[A,B](x: B) extends Either[A,B] with Monad[B]
  def flatMap[X,Y,M[X]<:Monad[X]](m: M[X], f: X => M[Y]): M[Y] = f(m.x)
  println(flatMap(Left(1), {x: Int => Left(x)}))
}
error: type mismatch:
 found   : => _$hk$0(M[X]#x)
 required: X
  def flatMap[X,Y,M[X]<:Monad[X]](m: M[X], f: X => M[Y]): M[Y] = f(m.x)
                                                                     ^
error: type mismatch:
 found   : Test.this.Left[Nothing', Nothing']
 required: Nothing'{_$hk$0 = Nothing'}
  println(flatMap(Left(1), {x: Int => Left(x)}))
                      ^
error: type mismatch:
 found   : Test.this.Left[Nothing', Nothing']
 required: Nothing'{_$hk$0 = Y?}
  println(flatMap(Left(1), {x: Int => Left(x)}))
                                          ^
three errors found

Similar, with M not upper bounded and flatMap not implemented:

trait Test {
  trait Monad[X] {
    def x: X
  }
  sealed abstract class Either[A,B]
  case class Left[A,B](x: A) extends Either[A,B] with Monad[A]
  case class Right[A,B](x: B) extends Either[A,B] with Monad[B]
  def flatMap[X,Y,M[X]](m: M[X], f: X => M[Y]): M[Y]
  println(flatMap(Left(1), {x: Int => Left(x)}))
}
error: type mismatch:
 found   : Test.this.Left[Nothing', Nothing']
 required: Nothing'{_$hk$0 = Nothing'}
  println(flatMap(Left(1), {x: Int => Left(x)}))
                      ^
 found   : Test.this.Left[Nothing', Nothing']
 required: Nothing'{_$hk$0 = Y?}
  println(flatMap(Left(1), {x: Int => Left(x)}))
                                          ^
two errors found

This one actually works in Dotty with final val flagDeepSubTypeRecursions = false in Config (if true, the assertion in TypeComparer.monitoredSubtype fails.

trait Test {
  def flatMap[X,Y,M[X]](m: M[X], f: X => M[Y]): M[Y]
  println(flatMap(Some(1), {x: Int => Some(x)}))
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants