This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Type constructor inference of partially-applied type constructors

2 replies
Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.

With Scala 2.7 I was able to wrap partially-applied type constructors,
however, this required me to explicitly enumerate each type
constructor because the higher-kinded type variable was never inferred.

With Scala 2.8, I am now able to infer this type variable, thus not
requiring me to list each type constructor. This can be seen by the
single method MA.ma below. However, partially-applied type
constructors will not infer. Further, I cannot explicitly specify each
type constructor (in this case, forall A. Function1[_, A]) without
giving up my higher-kinded inference due to ambiguity.

I hope I have explained this problem well enough, as it severely
cripples the capabilities of Scala's higher-kinded inference. A
minimal demonstration code example follows.

package boo

trait PartialApply1Of2[T[_, _], A] {
type Flip[B] = T[B, A]
}

trait Cofunctor[F[_]] {
def comap[A, B](r: F[A], f: B => A): F[B]
}

object Cofunctor {
implicit def Function1Cofunctor[X]:
Cofunctor[PartialApply1Of2[Function1, X]#Flip] = new
Cofunctor[PartialApply1Of2[Function1, X]#Flip] {
def comap[A, B](r: A => X, f: B => A) = r compose f
}
}

sealed trait MA[M[_], A] {
val v: M[A]

def ∙[B](f: B => A)(implicit t: Cofunctor[M]) = t.comap(v, f)
}

object MA {
implicit def ma[M[_], A](a: M[A]) = new MA[M, A] {
val v = a
}
}

////

object Example {
import MA._

def main(args: Array[String]) {
{
// I would like to write this:
// val f: Int => Int = (3+)

// Instead of having to write this:
val f = ma[PartialApply1Of2[Function1, Int]#Flip, Int](3+)

// List(3, 4, 4, 5, 5)
println(List(1, 2, 3, 4, 5) map (f ∙ ((_: Int) / 2)))
}
}
}

Adriaan Moors
Joined: 2009-04-03,
User offline. Last seen 42 years 45 weeks ago.
Re: Type constructor inference of partially-applied type const
sorry, this is out of reach for now as it requires higher-order unification -- we could (try to) implement Partial polymorphic type inference and higher-order unification but that's going to take a while... 
please add your thoughts to http://lampsvn.epfl.ch/trac/scala/ticket/2712

adriaan

On Fri, Nov 27, 2009 at 3:37 AM, Tony Morris <tonymorris@gmail.com> wrote:

With Scala 2.7 I was able to wrap partially-applied type constructors,
however, this required me to explicitly enumerate each type
constructor because the higher-kinded type variable was never inferred.

With Scala 2.8, I am now able to infer this type variable, thus not
requiring me to list each type constructor. This can be seen by the
single method MA.ma below. However, partially-applied type
constructors will not infer. Further, I cannot explicitly specify each
type constructor (in this case, forall A. Function1[_, A]) without
giving up my higher-kinded inference due to ambiguity.

I hope I have explained this problem well enough, as it severely
cripples the capabilities of Scala's higher-kinded inference. A
minimal demonstration code example follows.



package boo

trait PartialApply1Of2[T[_, _], A] {
 type Flip[B] = T[B, A]
}

trait Cofunctor[F[_]] {
 def comap[A, B](r: F[A], f: B => A): F[B]
}

object Cofunctor {
 implicit def Function1Cofunctor[X]:
Cofunctor[PartialApply1Of2[Function1, X]#Flip] = new
Cofunctor[PartialApply1Of2[Function1, X]#Flip] {
   def comap[A, B](r: A => X, f: B => A) = r compose f
 }
}

sealed trait MA[M[_], A] {
 val v: M[A]

 def ∙[B](f: B => A)(implicit t: Cofunctor[M]) = t.comap(v, f)
}

object MA {
 implicit def ma[M[_], A](a: M[A]) = new MA[M, A] {
   val v = a
 }
}

////

object Example {
 import MA._

 def main(args: Array[String]) {
   {
     // I would like to write this:
     // val f: Int => Int = (3+)

     // Instead of having to write this:
     val f = ma[PartialApply1Of2[Function1, Int]#Flip, Int](3+)

     // List(3, 4, 4, 5, 5)
     println(List(1, 2, 3, 4, 5) map (f ∙ ((_: Int) / 2)))
   }
 }
}


Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: Type constructor inference of partially-applied type const
Good... I ran into this a while ago, but hadn't recalled if it worked in 2.7.x or not.

- Josh

On Fri, Nov 27, 2009 at 6:16 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
sorry, this is out of reach for now as it requires higher-order unification -- we could (try to) implement Partial polymorphic type inference and higher-order unification but that's going to take a while... 
please add your thoughts to http://lampsvn.epfl.ch/trac/scala/ticket/2712

adriaan

On Fri, Nov 27, 2009 at 3:37 AM, Tony Morris <tonymorris@gmail.com> wrote:

With Scala 2.7 I was able to wrap partially-applied type constructors,
however, this required me to explicitly enumerate each type
constructor because the higher-kinded type variable was never inferred.

With Scala 2.8, I am now able to infer this type variable, thus not
requiring me to list each type constructor. This can be seen by the
single method MA.ma below. However, partially-applied type
constructors will not infer. Further, I cannot explicitly specify each
type constructor (in this case, forall A. Function1[_, A]) without
giving up my higher-kinded inference due to ambiguity.

I hope I have explained this problem well enough, as it severely
cripples the capabilities of Scala's higher-kinded inference. A
minimal demonstration code example follows.



package boo

trait PartialApply1Of2[T[_, _], A] {
 type Flip[B] = T[B, A]
}

trait Cofunctor[F[_]] {
 def comap[A, B](r: F[A], f: B => A): F[B]
}

object Cofunctor {
 implicit def Function1Cofunctor[X]:
Cofunctor[PartialApply1Of2[Function1, X]#Flip] = new
Cofunctor[PartialApply1Of2[Function1, X]#Flip] {
   def comap[A, B](r: A => X, f: B => A) = r compose f
 }
}

sealed trait MA[M[_], A] {
 val v: M[A]

 def ∙[B](f: B => A)(implicit t: Cofunctor[M]) = t.comap(v, f)
}

object MA {
 implicit def ma[M[_], A](a: M[A]) = new MA[M, A] {
   val v = a
 }
}

////

object Example {
 import MA._

 def main(args: Array[String]) {
   {
     // I would like to write this:
     // val f: Int => Int = (3+)

     // Instead of having to write this:
     val f = ma[PartialApply1Of2[Function1, Int]#Flip, Int](3+)

     // List(3, 4, 4, 5, 5)
     println(List(1, 2, 3, 4, 5) map (f ∙ ((_: Int) / 2)))
   }
 }
}


Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland