Skip to content

Instantly share code, notes, and snippets.

@jedws
Last active December 23, 2015 19:09
Show Gist options
  • Select an option

  • Save jedws/6681072 to your computer and use it in GitHub Desktop.

Select an option

Save jedws/6681072 to your computer and use it in GitHub Desktop.
@hg_ just showed me this, pretty odd: can't create a subInstance Root as a val, but can as an object
import scalaz._, Scalaz._
trait Root {
type FT[A[+_], +B]
val FT: MonadTrans[FT]
def value: FT[Id, Unit]
}
trait Child extends Root { child =>
// error: an't existentially abstract over parameterized type A
/*val subInstance = new Root {
type FT[A[+_], +B] = child.FT[A, B]
val FT = child.FT
def value = FT.liftM(().point[Id])
}*/
// totally fine
object subInstance extends Root {
type FT[A[+_], +B] = child.FT[A, B]
val FT = child.FT
def value = FT.liftM(().point[Id])
}
def value = subInstance.value
}
@hgiddens
Copy link

import language.higherKinds

trait MonadTrans[F[_[+_], +_]] {
  def liftM[A[+_], B](a: A[B]): F[A, B]
}

trait Root {
  type FT[A[+_], +B]
  val FT: MonadTrans[FT]
  def value: FT[List, Unit]
}

trait Child extends Root { child =>
  // error: can't existentially abstract over parameterized type A
  val subInstance = new Root {
    type FT[A[+_], +B] = child.FT[A, B]
    val FT = child.FT
    def value = FT.liftM(List[Unit]())
  }

  // totally fine
  object subInstance extends Root {
    type FT[A[+_], +B] = child.FT[A, B]
    val FT = child.FT
    def value = FT.liftM(List[Unit]())
  }

  def value = subInstance.value
}

@hgiddens
Copy link

Oh yeah, and were FT to be a unary type constructor e.g. FT[+A] the val works fine

@jedws
Copy link
Author

jedws commented Sep 24, 2013

Eero found the following explanation:

http://stackoverflow.com/questions/3122398/cant-existentially-abstract-over-parameterized-type

So, it isn't a bug, it is documented behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment