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

multiple type parameter lists #4719

Open
scabug opened this issue Jun 20, 2011 · 4 comments

Comments

@scabug
Copy link

commented Jun 20, 2011

(quoting Miles Sabin)

We can encode multiple type parameter blocks on
methods in current Scala, albeit inefficiently and clumsily,

 def foo[A1, A2][B1, B2](p1 : (A1, B1)) : (A2, B2) = ...

can be encoded as,

 def foo[A1, A2] = new { def apply[X1, X2, B1, B2](p1 : (A1,
B1))(implicit ev : X1 =:= A1) : (A2, B2) = ... }

(/quoting Miles Sabin)

Multiple type parameter lists would internally be represented by nested PolyTypes, which is possible due to the NullaryMethodType refactoring. I see two options for type inference:

  • reduce to single type parameter list by bunching all type parameters together
  • solve type parameters in batches, so that the concrete type chosen for later type parameters does not influence the inference of earlier type parameters (in lists on the left), au contraire, later type param's inference depends on the types chosen for type params in lists on their left (see also fundeps in haskell)

see also: named and default type parameters

@scabug

This comment has been minimized.

Copy link
Author

commented Jun 20, 2011

@scabug

This comment has been minimized.

Copy link
Author

commented Jun 20, 2011

@milessabin said:
I was assuming option (2) would be the way to go, if only for consistency with the semantics of multiple value parameter lists.

@scabug

This comment has been minimized.

Copy link
Author

commented Apr 19, 2014

@Atry said (edited on Apr 19, 2014 3:19:57 AM UTC):

type ResultOf[Function] = {
  type Result
}
object ResultOf {
  type ResultOfFunction1[A, R] = ResultOf[A => R] {
    type Result = R
  }
  implicit def resultOfFunction1[A, R]: ResultOfFunction1[A, R] = null
}
def betterImplicitly[RequiredType][ActuallyType](implicit i: RequiredType with ActuallyType) = i
val functionTypeTrait = betterImplicitly[ResultOf[String => Int]]
val shouldBeInt: functionTypeTrait.Result = 0

With multiple type parameter lists support, we will have a better implicitly method, which infers a specified type instead of the required type.

@nbenns

This comment has been minimized.

Copy link

commented May 2, 2017

It would be nice to have multiple parameter lists on type aliases as well:

Then I could turn this mess:

import scala.language.higherKinds

type Curry2[F[_, _]] = {
  type Apply[A] = {
    type Apply[B] = F[A, B]
  }
}

trait Functor[F[_]] {
  def map[A, B](op: A => B)(orig: F[A]): F[B]
}

type Reader = Curry2[Function]

implicit def ReaderFunctor[R] = new Functor[Reader#Apply[R]#Apply] {
  override def map[A, B](op: A => B)(orig: R => A): R => B =
    orig andThen op
}

def map[A,B,F[_]](op: A => B)(fa: F[A])(implicit functor: Functor[F]): F[B] =
  functor.map(op)(fa)

def toStringContainer[F[_]](a: F[Int])(implicit functor: Functor[F]) = map[Int, String, F](_.toString)(a)

val id: Int => Int = identity

val out: Int => String = toStringContainer[Reader#Apply[Int]#Apply](id)
out(2)

into:

import scala.language.higherKinds

type Curry2[F[_, _]][A][B] = F[A, B]

trait Functor[F[_]] {
  def map[A, B](op: A => B)(orig: F[A]): F[B]
}

type Reader = Curry2[Function]

implicit def ReaderFunctor[R] = new Functor[Reader[R]] {
  override def map[A, B](op: A => B)(orig: R => A): R => B =
    orig andThen op
}

def map[A,B][F[_]](op: A => B)(fa: F[A])(implicit functor: Functor[F]): F[B] =
  functor.map(op)(fa)

/*
  Not sure if it would be possible to get this clean,
  or if the implicit would cause this to fail.
  Might also have to pass toString like `(_:Int).toString`
*/
def toStringContainer = map(_.toString)

val id: Int => Int = identity

val out: Int => String = toStringContainer[Reader[Int]](id)
out(2)

An alternative would be to implement Apply for type parameters on the first example, at least it would clean up the use of the parameters instead of using the projection syntax.

A note that the kind projection plugin only fixes some of these issues, but not all.

@SethTisue SethTisue removed quickfix labels Feb 5, 2018

@adriaanm adriaanm removed their assignment Sep 28, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.