type parameter definition in scala [duplicate] - scala

Sometime I stumble into the semi-mysterious notation of
def f[T](..) = new T[({type l[A]=SomeType[A,..]})#l] {..}
in Scala blog posts, which give it a "we used that type-lambda trick" handwave.
While I have some intutition about this (we gain an anonymous type parameter A without having to pollute the definition with it?), I found no clear source describing what the type lambda trick is, and what are its benefits. Is it just syntactic sugar, or does it open some new dimensions?

Type lambdas are vital quite a bit of the time when you are working with higher-kinded types.
Consider a simple example of defining a monad for the right projection of Either[A, B]. The monad typeclass looks like this:
trait Monad[M[_]] {
def point[A](a: A): M[A]
def bind[A, B](m: M[A])(f: A => M[B]): M[B]
}
Now, Either is a type constructor of two arguments, but to implement Monad, you need to give it a type constructor of one argument. The solution to this is to use a type lambda:
class EitherMonad[A] extends Monad[({type λ[α] = Either[A, α]})#λ] {
def point[B](b: B): Either[A, B]
def bind[B, C](m: Either[A, B])(f: B => Either[A, C]): Either[A, C]
}
This is an example of currying in the type system - you have curried the type of Either, such that when you want to create an instance of EitherMonad, you have to specify one of the types; the other of course is supplied at the time you call point or bind.
The type lambda trick exploits the fact that an empty block in a type position creates an anonymous structural type. We then use the # syntax to get a type member.
In some cases, you may need more sophisticated type lambdas that are a pain to write out inline. Here's an example from my code from today:
// types X and E are defined in an enclosing scope
private[iteratee] class FG[F[_[_], _], G[_]] {
type FGA[A] = F[G, A]
type IterateeM[A] = IterateeT[X, E, FGA, A]
}
This class exists exclusively so that I can use a name like FG[F, G]#IterateeM to refer to the type of the IterateeT monad specialized to some transformer version of a second monad which is specialized to some third monad. When you start to stack, these kinds of constructs become very necessary. I never instantiate an FG, of course; it's just there as a hack to let me express what I want in the type system.

The benefits are exactly the same as those conferred by anonymous functions.
def inc(a: Int) = a + 1; List(1, 2, 3).map(inc)
List(1, 2, 3).map(a => a + 1)
An example usage, with Scalaz 7. We want to use a Functor that can map a function over the second element in a Tuple2.
type IntTuple[+A]=(Int, A)
Functor[IntTuple].map((1, 2))(a => a + 1)) // (1, 3)
Functor[({type l[a] = (Int, a)})#l].map((1, 2))(a => a + 1)) // (1, 3)
Scalaz provides some implicit conversions that can infer the type argument to Functor, so we often avoid writing these altogether. The previous line can be rewritten as:
(1, 2).map(a => a + 1) // (1, 3)
If you use IntelliJ, you can enable Settings, Code Style, Scala, Folding, Type Lambdas. This then hides the crufty parts of the syntax, and presents the more palatable:
Functor[[a]=(Int, a)].map((1, 2))(a => a + 1)) // (1, 3)
A future version of Scala might directly support such a syntax.

To put things in context: This answer was originally posted in another thread. You are seeing it here because the two threads have been merged. The question statement in the said thread was as follows:
How to resolve this type definition: Pure[({type ?[a]=(R, a)})#?] ?
What are the reasons of using such construction?
Snipped comes from scalaz library:
trait Pure[P[_]] {
def pure[A](a: => A): P[A]
}
object Pure {
import Scalaz._
//...
implicit def Tuple2Pure[R: Zero]: Pure[({type ?[a]=(R, a)})#?] = new Pure[({type ?[a]=(R, a)})#?] {
def pure[A](a: => A) = (Ø, a)
}
//...
}
Answer:
trait Pure[P[_]] {
def pure[A](a: => A): P[A]
}
The one underscore in the boxes after P implies that it is a type constructor takes one type and returns another type. Examples of type constructors with this kind: List, Option.
Give List an Int, a concrete type, and it gives you List[Int], another concrete type. Give List a String and it gives you List[String]. Etc.
So, List, Option can be considered to be type level functions of arity 1. Formally we say, they have a kind * -> *. The asterisk denotes a type.
Now Tuple2[_, _] is a type constructor with kind (*, *) -> * i.e. you need to give it two types to get a new type.
Since their signatures do not match, you cannot substitute Tuple2 for P. What you need to do is partially apply Tuple2 on one of its arguments, which will give us a type constructor with kind * -> *, and we can substitue it for P.
Unfortunately Scala has no special syntax for partial application of type constructors, and so we have to resort to the monstrosity called type lambdas. (What you have in your example.) They are called that because they are analogous to lambda expressions that exist at value level.
The following example might help:
// VALUE LEVEL
// foo has signature: (String, String) => String
scala> def foo(x: String, y: String): String = x + " " + y
foo: (x: String, y: String)String
// world wants a parameter of type String => String
scala> def world(f: String => String): String = f("world")
world: (f: String => String)String
// So we use a lambda expression that partially applies foo on one parameter
// to yield a value of type String => String
scala> world(x => foo("hello", x))
res0: String = hello world
// TYPE LEVEL
// Foo has a kind (*, *) -> *
scala> type Foo[A, B] = Map[A, B]
defined type alias Foo
// World wants a parameter of kind * -> *
scala> type World[M[_]] = M[Int]
defined type alias World
// So we use a lambda lambda that partially applies Foo on one parameter
// to yield a type of kind * -> *
scala> type X[A] = World[({ type M[A] = Foo[String, A] })#M]
defined type alias X
// Test the equality of two types. (If this compiles, it means they're equal.)
scala> implicitly[X[Int] =:= Foo[String, Int]]
res2: =:=[X[Int],Foo[String,Int]] = <function1>
Edit:
More value level and type level parallels.
// VALUE LEVEL
// Instead of a lambda, you can define a named function beforehand...
scala> val g: String => String = x => foo("hello", x)
g: String => String = <function1>
// ...and use it.
scala> world(g)
res3: String = hello world
// TYPE LEVEL
// Same applies at type level too.
scala> type G[A] = Foo[String, A]
defined type alias G
scala> implicitly[X =:= Foo[String, Int]]
res5: =:=[X,Foo[String,Int]] = <function1>
scala> type T = World[G]
defined type alias T
scala> implicitly[T =:= Foo[String, Int]]
res6: =:=[T,Foo[String,Int]] = <function1>
In the case you have presented, the type parameter R is local to function Tuple2Pure and so you cannot simply define type PartialTuple2[A] = Tuple2[R, A], because there is simply no place where you can put that synonym.
To deal with such a case, I use the following trick that makes use of type members. (Hopefully the example is self-explanatory.)
scala> type Partial2[F[_, _], A] = {
| type Get[B] = F[A, B]
| }
defined type alias Partial2
scala> implicit def Tuple2Pure[R]: Pure[Partial2[Tuple2, R]#Get] = sys.error("")
Tuple2Pure: [R]=> Pure[[B](R, B)]

Related

In Scala, how to summon a polymorphic function applicable to an input type, without knowing the output type or full type arguments?

Since Scala 2.12 (or is it 2.13, can't be sure), the compiler can infer latent type arguments across multiple methods:
def commutative[
A,
B
]: ((A, B) => (B, A)) = {???} // implementing omitted
val a = (1 -> "a")
val b = commutative.apply(a)
The last line successfully inferred A = Int, B = String, unfortunately, this requires an instance a: (Int, String) to be given.
Now I'd like to twist this API for a bit and define the following function:
def findApplicable[T](fn: Any => Any)
Such that findApplicable[(Int, String)](commutative) automatically generate the correct function specialised for A = Int, B = String. Is there a way to do it within the language's capability? Or I'll have to upgrade to scala 3 to do this?
UPDATE 1 it should be noted that the output of commutative can be any type, not necessarily a Function2, e.g. I've tried the following definition:
trait SummonedFn[-I, +O] extends (I => O) {
final def summon[II <: I]: this.type = this
}
Then redefine commutative to use it:
def commutative[
A,
B
]: SummonedFn[(A, B), (B, A)] = {???} // implementing omitted
val b = commutative.summon[(Int, String)]
Oops, this doesn't work, type parameters don't get equal treatment like value parameters
If at some point some call-site knows the types of arguments (they aren't actually Any => Any) it is doable using type classes:
trait Commutative[In, Out] {
def swap(in: In): Out
}
object Commutative {
def swap[In, Out](in: In)(implicit c: Commutative[In, Out]): Out =
c.swap(in)
implicit def tuple2[A, B]: Commutative[(A, B), (B, A)] =
in => in.swap
}
At call site:
def use[In, Out](ins: List[In])(implicit c: Commutative[In, Out]): List[Out] =
ins.map(Commutative.swap(_))
However, this way you have to pass both In as well as Out as type parameters. If there are multiple possible Outs for a single In type, then there is not much you can do.
But if you want to have Input type => Output type implication, you can use dependent types:
trait Commutative[In] {
type Out
def swap(in: In): Out
}
object Commutative {
// help us transform dependent types back into generics
type Aux[In, Out0] = Commutative[In] { type Out = Out0 }
def swap[In](in: In)(implicit c: Commutative[In]): c.Out =
c.swap(in)
implicit def tuple2[A, B]: Commutative.Aux[(A, B), (B, A)] =
in => in.swap
}
Call site:
// This code is similar to the original code, but when the compiler
// will be looking for In it will automatically figure Out.
def use[In, Out](ins: List[In])(implicit c: Commutative.Aux[In, Out]): List[Out] =
ins.map(Commutative.swap(_))
// Alternatively, without Aux pattern:
def use2[In](ins: List[In])(implicit c: Commutative[In]): List[c.Out] =
ins.map(Commutative.swap(_))
def printMapped(list: List[(Int, String)]): Unit =
println(list)
// The call site that knows the input and provides implicit
// will also know the exact Out type.
printMapped(use(List("a" -> 1, "b" -> 2)))
printMapped(use2(List("a" -> 1, "b" -> 2)))
That's how you can solve the issue when you know the exact input type. If you don't know it... then you cannot use compiler (neither in Scala 2 nor in Scala 3) to generate this behavior as you have to implement this functionality using some runtime reflection, e.g. checking types using isInstanceOf, casting to some assumed types and then running predefined behavior etc.
I'm not sure I understand the question 100%, but it seems like you want to do some kind of advanced partial type application. Usually you can achieve such an API by introducing an intermediary class. And to preserve as much type information as possible you can use a method with a dependent return type.
class FindApplicablePartial[A] {
def apply[B](fn: A => B): fn.type = fn
}
def findApplicable[A] = new FindApplicablePartial[A]
scala> def result = findApplicable[(Int, String)](commutative)
def result: SummonedFn[(Int, String),(String, Int)]
And actually in this case since findApplicable itself doesn't care about type B (i.e. B doesn't have a context bound or other uses), you don't even need the intermediary class, but can use a wildcard/existential type instead:
def findApplicable[A](fn: A => _): fn.type = fn
This works just as well.

Scala generic multiple type variant [duplicate]

One way that has been suggested to deal with double definitions of overloaded methods is to replace overloading with pattern matching:
object Bar {
def foo(xs: Any*) = xs foreach {
case _:String => println("str")
case _:Int => println("int")
case _ => throw new UglyRuntimeException()
}
}
This approach requires that we surrender static type checking on the arguments to foo. It would be much nicer to be able to write
object Bar {
def foo(xs: (String or Int)*) = xs foreach {
case _: String => println("str")
case _: Int => println("int")
}
}
I can get close with Either, but it gets ugly fast with more than two types:
type or[L,R] = Either[L,R]
implicit def l2Or[L,R](l: L): L or R = Left(l)
implicit def r2Or[L,R](r: R): L or R = Right(r)
object Bar {
def foo(xs: (String or Int)*) = xs foreach {
case Left(l) => println("str")
case Right(r) => println("int")
}
}
It looks like a general (elegant, efficient) solution would require defining Either3, Either4, .... Does anyone know of an alternate solution to achieve the same end? To my knowledge, Scala does not have built-in "type disjunction". Also, are the implicit conversions defined above lurking in the standard library somewhere so that I can just import them?
Miles Sabin describes a very nice way to get union type in his recent blog post Unboxed union types in Scala via the Curry-Howard isomorphism:
He first defines negation of types as
type ¬[A] = A => Nothing
using De Morgan's law this allows him to define union types
type ∨[T, U] = ¬[¬[T] with ¬[U]]
With the following auxiliary constructs
type ¬¬[A] = ¬[¬[A]]
type |∨|[T, U] = { type λ[X] = ¬¬[X] <:< (T ∨ U) }
you can write union types as follows:
def size[T : (Int |∨| String)#λ](t : T) = t match {
case i : Int => i
case s : String => s.length
}
Well, in the specific case of Any*, this trick below won't work, as it will not accept mixed types. However, since mixed types wouldn't work with overloading either, this may be what you want.
First, declare a class with the types you wish to accept as below:
class StringOrInt[T]
object StringOrInt {
implicit object IntWitness extends StringOrInt[Int]
implicit object StringWitness extends StringOrInt[String]
}
Next, declare foo like this:
object Bar {
def foo[T: StringOrInt](x: T) = x match {
case _: String => println("str")
case _: Int => println("int")
}
}
And that's it. You can call foo(5) or foo("abc"), and it will work, but try foo(true) and it will fail. This could be side-stepped by the client code by creating a StringOrInt[Boolean], unless, as noted by Randall below, you make StringOrInt a sealed class.
It works because T: StringOrInt means there's an implicit parameter of type StringOrInt[T], and because Scala looks inside companion objects of a type to see if there are implicits there to make code asking for that type work.
Dotty, a new experimental Scala compiler, supports union types (written A | B), so you can do exactly what you wanted:
def foo(xs: (String | Int)*) = xs foreach {
case _: String => println("str")
case _: Int => println("int")
}
Here is the Rex Kerr way to encode union types. Straight and simple!
scala> def f[A](a: A)(implicit ev: (Int with String) <:< A) = a match {
| case i: Int => i + 1
| case s: String => s.length
| }
f: [A](a: A)(implicit ev: <:<[Int with String,A])Int
scala> f(3)
res0: Int = 4
scala> f("hello")
res1: Int = 5
scala> f(9.2)
<console>:9: error: Cannot prove that Int with String <:< Double.
f(9.2)
^
Source: Comment #27 under this excellent blog post by Miles Sabin which provides another way of encoding union types in Scala.
It's possible to generalize Daniel's solution as follows:
sealed trait Or[A, B]
object Or {
implicit def a2Or[A,B](a: A) = new Or[A, B] {}
implicit def b2Or[A,B](b: B) = new Or[A, B] {}
}
object Bar {
def foo[T <% String Or Int](x: T) = x match {
case _: String => println("str")
case _: Int => println("int")
}
}
The main drawbacks of this approach are
As Daniel pointed out, it does not handle collections/varargs with mixed types
The compiler does not issue a warning if the match is not exhaustive
The compiler does not issue an error if the match includes an impossible case
Like the Either approach, further generalization would require defining analogous Or3, Or4, etc. traits. Of course, defining such traits would be much simpler than defining the corresponding Either classes.
Update:
Mitch Blevins demonstrates a very similar approach and shows how to generalize it to more than two types, dubbing it the "stuttering or".
I have sort of stumbled on a relatively clean implementation of n-ary union types by combining the notion of type lists with a simplification of Miles Sabin's work in this area, which someone mentions in another answer.
Given type ¬[-A] which is contravariant on A, by definition given A <: B we can write
¬[B] <: ¬[A], inverting the ordering of types.
Given types A, B, and X, we want to express X <: A || X <: B.
Applying contravariance, we get ¬[A] <: ¬[X] || ¬[B] <: ¬[X]. This can in turn
be expressed as ¬[A] with ¬[B] <: ¬[X] in which one of A or B must be a supertype of X or X itself (think about function arguments).
object Union {
import scala.language.higherKinds
sealed trait ¬[-A]
sealed trait TSet {
type Compound[A]
type Map[F[_]] <: TSet
}
sealed trait ∅ extends TSet {
type Compound[A] = A
type Map[F[_]] = ∅
}
// Note that this type is left-associative for the sake of concision.
sealed trait ∨[T <: TSet, H] extends TSet {
// Given a type of the form `∅ ∨ A ∨ B ∨ ...` and parameter `X`, we want to produce the type
// `¬[A] with ¬[B] with ... <:< ¬[X]`.
type Member[X] = T#Map[¬]#Compound[¬[H]] <:< ¬[X]
// This could be generalized as a fold, but for concision we leave it as is.
type Compound[A] = T#Compound[H with A]
type Map[F[_]] = T#Map[F] ∨ F[H]
}
def foo[A : (∅ ∨ String ∨ Int ∨ List[Int])#Member](a: A): String = a match {
case s: String => "String"
case i: Int => "Int"
case l: List[_] => "List[Int]"
}
foo(42)
foo("bar")
foo(List(1, 2, 3))
foo(42d) // error
foo[Any](???) // error
}
I did spend some time trying to combine this idea with an upper bound on member types as seen in the TLists of harrah/up, however the implementation of Map with type bounds has thus far proved challenging.
A type class solution is probably the nicest way to go here, using implicits.
This is similar to the monoid approach mentioned in the Odersky/Spoon/Venners book:
abstract class NameOf[T] {
def get : String
}
implicit object NameOfStr extends NameOf[String] {
def get = "str"
}
implicit object NameOfInt extends NameOf[Int] {
def get = "int"
}
def printNameOf[T](t:T)(implicit name : NameOf[T]) = println(name.get)
If you then run this in the REPL:
scala> printNameOf(1)
int
scala> printNameOf("sss")
str
scala> printNameOf(2.0f)
<console>:10: error: could not find implicit value for parameter nameOf: NameOf[
Float]
printNameOf(2.0f)
^
We’d like a type operator Or[U,V] that can be used to constrain a type parameters X in such a way that either X <: U or X <: V. Here's a definition that comes about as close as we can get:
trait Inv[-X]
type Or[U,T] = {
type pf[X] = (Inv[U] with Inv[T]) <:< Inv[X]
}
Here is how it's used:
// use
class A; class B extends A; class C extends B
def foo[X : (B Or String)#pf] = {}
foo[B] // OK
foo[C] // OK
foo[String] // OK
foo[A] // ERROR!
foo[Number] // ERROR!
This uses a few Scala type tricks. The main one is the use of generalized type constraints. Given types U and V, the Scala compiler provides a class called U <:< V (and an implicit object of that class) if and only if the Scala compiler can prove that U is a subtype of V. Here’s a simpler example using generalized type constraints that works for some cases:
def foo[X](implicit ev : (B with String) <:< X) = {}
This example works when X an instance of class B, a String, or has a type that is neither a supertype nor a subtype of B or String. In the first two cases, it’s true by the definition of the with keyword that (B with String) <: B and (B with String) <: String, so Scala will provide an implicit object that will be passed in as ev: the Scala compiler will correctly accept foo[B] and foo[String].
In the last case, I’m relying on the fact that if U with V <: X, then U <: X or V <: X. It seems intuitively true, and I’m simply assuming it. It’s clear from this assumption why this simple example fails when X is a supertype or subtype of either B or String: for example, in the example above, foo[A] is incorrectly accepted and foo[C] is incorrectly rejected. Again, what we want is some kind of type expression on the variables U, V, and X that is true exactly when X <: U or X <: V.
Scala’s notion of contravariance can help here. Remember the trait trait Inv[-X]? Because it is contravariant in its type parameter X, Inv[X] <: Inv[Y] if and only if Y <: X. That means that we can replace the example above with one that actually will work:
trait Inv[-X]
def foo[X](implicit ev : (Inv[B] with Inv[String]) <:< Inv[X]) = {}
That’s because the expression (Inv[U] with Inv[V]) <: Inv[X] is true, by the same assumption above, exactly when Inv[U] <: Inv[X] or Inv[V] <: Inv[X], and by the definition of contravariance, this is true exactly when X <: U or X <: V.
It’s possible to make things a little more reusable by declaring a parametrizable type BOrString[X] and using it as follows:
trait Inv[-X]
type BOrString[X] = (Inv[B] with Inv[String]) <:< Inv[X]
def foo[X](implicit ev : BOrString[X]) = {}
Scala will now attempt to construct the type BOrString[X] for every X that foo is called with, and the type will be constructed precisely when X is a subtype of either B or String. That works, and there is a shorthand notation. The syntax below is equivalent (except that ev must now be referenced in the method body as implicitly[BOrString[X]] rather than simply ev) and uses BOrString as a type context bound:
def foo[X : BOrString] = {}
What we’d really like is a flexible way to create a type context bound. A type context must be a parametrizable type, and we want a parametrizable way to create one. That sounds like we’re trying to curry functions on types just like we curry functions on values. In other words, we’d like something like the following:
type Or[U,T][X] = (Inv[U] with Inv[T]) <:< Inv[X]
That’s not directly possible in Scala, but there is a trick we can use to get pretty close. That brings us to the definition of Or above:
trait Inv[-X]
type Or[U,T] = {
type pf[X] = (Inv[U] with Inv[T]) <:< Inv[X]
}
Here we use structural typing and Scala’s pound operator to create a structural type Or[U,T] that is guaranteed to have one internal type. This is a strange beast. To give some context, the function def bar[X <: { type Y = Int }](x : X) = {} must be called with subclasses of AnyRef that have a type Y defined in them:
bar(new AnyRef{ type Y = Int }) // works!
Using the pound operator allows us to refer to the inner type Or[B, String]#pf, and using infix notation for the type operator Or, we arrive at our original definition of foo:
def foo[X : (B Or String)#pf] = {}
We can use the fact that function types are contravariant in their first type parameter in order to avoid defining the trait Inv:
type Or[U,T] = {
type pf[X] = ((U => _) with (T => _)) <:< (X => _)
}
There is also this hack:
implicit val x: Int = 0
def foo(a: List[Int])(implicit ignore: Int) { }
implicit val y = ""
def foo(a: List[String])(implicit ignore: String) { }
foo(1::2::Nil)
foo("a"::"b"::Nil)
See Working around type erasure ambiguities (Scala).
You might take a look at MetaScala, which has something called OneOf. I get the impression that this doesn't work well with match statements but that you can simulate matching using higher-order functions. Take a look at this snippet, for instance, but note that the "simulated matching" part is commented out, maybe because it doesn't quite work yet.
Now for some editorializing: I don't think there's anything egregious about defining Either3, Either4, etc. as you describe. This is essentially dual to the standard 22 tuple types built in to Scala. It'd certainly be nice if Scala had built-in disjunctive types, and perhaps some nice syntax for them like {x, y, z}.
I am thinking that the first class disjoint type is a sealed supertype, with the alternate subtypes, and implicit conversions to/from the desired types of the disjunction to these alternative subtypes.
I assume this addresses comments 33 - 36 of Miles Sabin's solution, so the first class type that can be employed at the use site, but I didn't test it.
sealed trait IntOrString
case class IntOfIntOrString( v:Int ) extends IntOrString
case class StringOfIntOrString( v:String ) extends IntOrString
implicit def IntToIntOfIntOrString( v:Int ) = new IntOfIntOrString(v)
implicit def StringToStringOfIntOrString( v:String ) = new StringOfIntOrString(v)
object Int {
def unapply( t : IntOrString ) : Option[Int] = t match {
case v : IntOfIntOrString => Some( v.v )
case _ => None
}
}
object String {
def unapply( t : IntOrString ) : Option[String] = t match {
case v : StringOfIntOrString => Some( v.v )
case _ => None
}
}
def size( t : IntOrString ) = t match {
case Int(i) => i
case String(s) => s.length
}
scala> size("test")
res0: Int = 4
scala> size(2)
res1: Int = 2
One problem is Scala will not employ in case matching context, an implicit conversion from IntOfIntOrString to Int (and StringOfIntOrString to String), so must define extractors and use case Int(i) instead of case i : Int.
ADD: I responded to Miles Sabin at his blog as follows. Perhaps there are several improvements over Either:
It extends to more than 2 types, without any additional noise at the use or definition site.
Arguments are boxed implicitly, e.g. don't need size(Left(2)) or size(Right("test")).
The syntax of the pattern matching is implicitly unboxed.
The boxing and unboxing may be optimized away by the JVM hotspot.
The syntax could be the one adopted by a future first class union type, so migration could perhaps be seamless? Perhaps for the union type name, it would be better to use V instead of Or, e.g. IntVString, `Int |v| String`, `Int or String`, or my favorite `Int|String`?
UPDATE: Logical negation of the disjunction for the above pattern follows, and I added an alternative (and probably more useful) pattern at Miles Sabin's blog.
sealed trait `Int or String`
sealed trait `not an Int or String`
sealed trait `Int|String`[T,E]
case class `IntOf(Int|String)`( v:Int ) extends `Int|String`[Int,`Int or String`]
case class `StringOf(Int|String)`( v:String ) extends `Int|String`[String,`Int or String`]
case class `NotAn(Int|String)`[T]( v:T ) extends `Int|String`[T,`not an Int or String`]
implicit def `IntTo(IntOf(Int|String))`( v:Int ) = new `IntOf(Int|String)`(v)
implicit def `StringTo(StringOf(Int|String))`( v:String ) = new `StringOf(Int|String)`(v)
implicit def `AnyTo(NotAn(Int|String))`[T]( v:T ) = new `NotAn(Int|String)`[T](v)
def disjunction[T,E](x: `Int|String`[T,E])(implicit ev: E =:= `Int or String`) = x
def negationOfDisjunction[T,E](x: `Int|String`[T,E])(implicit ev: E =:= `not an Int or String`) = x
scala> disjunction(5)
res0: Int|String[Int,Int or String] = IntOf(Int|String)(5)
scala> disjunction("")
res1: Int|String[String,Int or String] = StringOf(Int|String)()
scala> disjunction(5.0)
error: could not find implicit value for parameter ev: =:=[not an Int or String,Int or String]
disjunction(5.0)
^
scala> negationOfDisjunction(5)
error: could not find implicit value for parameter ev: =:=[Int or String,not an Int or String]
negationOfDisjunction(5)
^
scala> negationOfDisjunction("")
error: could not find implicit value for parameter ev: =:=[Int or String,not an Int or String]
negationOfDisjunction("")
^
scala> negationOfDisjunction(5.0)
res5: Int|String[Double,not an Int or String] = NotAn(Int|String)(5.0)
ANOTHER UPDATE: Regarding comments 23 and 35 of Mile Sabin's solution, here is a way to declare a union type at the use site. Note it is unboxed after the first level, i.e. it has the advantage being extensible to any number of types in the disjunction, whereas Either needs nested boxing and the paradigm in my prior comment 41 was not extensible. In other words, a D[Int ∨ String] is assignable to (i.e. is a subtype of) a D[Int ∨ String ∨ Double].
type ¬[A] = (() => A) => A
type ∨[T, U] = ¬[T] with ¬[U]
class D[-A](v: A) {
def get[T](f: (() => T)) = v match {
case x : ¬[T] => x(f)
}
}
def size(t: D[Int ∨ String]) = t match {
case x: D[¬[Int]] => x.get( () => 0 )
case x: D[¬[String]] => x.get( () => "" )
case x: D[¬[Double]] => x.get( () => 0.0 )
}
implicit def neg[A](x: A) = new D[¬[A]]( (f: (() => A)) => x )
scala> size(5)
res0: Any = 5
scala> size("")
error: type mismatch;
found : java.lang.String("")
required: D[?[Int,String]]
size("")
^
scala> size("hi" : D[¬[String]])
res2: Any = hi
scala> size(5.0 : D[¬[Double]])
error: type mismatch;
found : D[(() => Double) => Double]
required: D[?[Int,String]]
size(5.0 : D[?[Double]])
^
Apparently the Scala compiler has three bugs.
It will not choose the correct implicit function for any type after the first type in the destination disjunction.
It doesn't exclude the D[¬[Double]] case from the match.
3.
scala> class D[-A](v: A) {
def get[T](f: (() => T))(implicit e: A <:< ¬[T]) = v match {
case x : ¬[T] => x(f)
}
}
error: contravariant type A occurs in covariant position in
type <:<[A,(() => T) => T] of value e
def get[T](f: (() => T))(implicit e: A <:< ?[T]) = v match {
^
The get method isn't constrained properly on input type, because the compiler won't allow A in the covariant position. One might argue that is a bug because all we want is evidence, we don't ever access the evidence in the function. And I made the choice not to test for case _ in the get method, so I wouldn't have to unbox an Option in the match in size().
March 05, 2012: The prior update needs an improvement. Miles Sabin's solution worked correctly with subtyping.
type ¬[A] = A => Nothing
type ∨[T, U] = ¬[T] with ¬[U]
class Super
class Sub extends Super
scala> implicitly[(Super ∨ String) <:< ¬[Super]]
res0: <:<[?[Super,String],(Super) => Nothing] =
scala> implicitly[(Super ∨ String) <:< ¬[Sub]]
res2: <:<[?[Super,String],(Sub) => Nothing] =
scala> implicitly[(Super ∨ String) <:< ¬[Any]]
error: could not find implicit value for parameter
e: <:<[?[Super,String],(Any) => Nothing]
implicitly[(Super ? String) <:< ?[Any]]
^
My prior update's proposal (for near first-class union type) broke subtyping.
scala> implicitly[D[¬[Sub]] <:< D[(Super ∨ String)]]
error: could not find implicit value for parameter
e: <:<[D[(() => Sub) => Sub],D[?[Super,String]]]
implicitly[D[?[Sub]] <:< D[(Super ? String)]]
^
The problem is that A in (() => A) => A appears in both the covariant (return type) and contravariant (function input, or in this case a return value of function which is a function input) positions, thus substitutions can only be invariant.
Note that A => Nothing is necessary only because we want A in the contravariant position, so that supertypes of A are not subtypes of D[¬[A]] nor D[¬[A] with ¬[U]] (see also). Since we only need double contravariance, we can achieve equivalent to Miles' solution even if we can discard the ¬ and ∨.
trait D[-A]
scala> implicitly[D[D[Super]] <:< D[D[Super] with D[String]]]
res0: <:<[D[D[Super]],D[D[Super] with D[String]]] =
scala> implicitly[D[D[Sub]] <:< D[D[Super] with D[String]]]
res1: <:<[D[D[Sub]],D[D[Super] with D[String]]] =
scala> implicitly[D[D[Any]] <:< D[D[Super] with D[String]]]
error: could not find implicit value for parameter
e: <:<[D[D[Any]],D[D[Super] with D[String]]]
implicitly[D[D[Any]] <:< D[D[Super] with D[String]]]
^
So the complete fix is.
class D[-A] (v: A) {
def get[T <: A] = v match {
case x: T => x
}
}
implicit def neg[A](x: A) = new D[D[A]]( new D[A](x) )
def size(t: D[D[Int] with D[String]]) = t match {
case x: D[D[Int]] => x.get[D[Int]].get[Int]
case x: D[D[String]] => x.get[D[String]].get[String]
case x: D[D[Double]] => x.get[D[Double]].get[Double]
}
Note the prior 2 bugs in Scala remain, but the 3rd one is avoided as T is now constrained to be subtype of A.
We can confirm the subtyping works.
def size(t: D[D[Super] with D[String]]) = t match {
case x: D[D[Super]] => x.get[D[Super]].get[Super]
case x: D[D[String]] => x.get[D[String]].get[String]
}
scala> size( new Super )
res7: Any = Super#1272e52
scala> size( new Sub )
res8: Any = Sub#1d941d7
I have been thinking that first-class intersection types are very important, both for the reasons Ceylon has them, and because instead of subsuming to Any which means unboxing with a match on expected types can generate a runtime error, the unboxing of a (heterogeneous collection containing a) disjunction can be type checked (Scala has to fix the bugs I noted). Unions are more straightforward than the complexity of using the experimental HList of metascala for heterogeneous collections.
There is another way which is slightly easier to understand if you do not grok Curry-Howard:
type v[A,B] = Either[Option[A], Option[B]]
private def L[A,B](a: A): v[A,B] = Left(Some(a))
private def R[A,B](b: B): v[A,B] = Right(Some(b))
// TODO: for more use scala macro to generate this for up to 22 types?
implicit def a2[A,B](a: A): v[A,B] = L(a)
implicit def b2[A,B](b: B): v[A,B] = R(b)
implicit def a3[A,B,C](a: A): v[v[A,B],C] = L(a2(a))
implicit def b3[A,B,C](b: B): v[v[A,B],C] = L(b2(b))
implicit def a4[A,B,C,D](a: A): v[v[v[A,B],C],D] = L(a3(a))
implicit def b4[A,B,C,D](b: B): v[v[v[A,B],C],D] = L(b3(b))
implicit def a5[A,B,C,D,E](a: A): v[v[v[v[A,B],C],D],E] = L(a4(a))
implicit def b5[A,B,C,D,E](b: B): v[v[v[v[A,B],C],D],E] = L(b4(b))
type JsonPrimtives = (String v Int v Double)
type ValidJsonPrimitive[A] = A => JsonPrimtives
def test[A : ValidJsonPrimitive](x: A): A = x
test("hi")
test(9)
// test(true) // does not compile
I use similar technique in dijon
Well, that's all very clever, but I'm pretty sure you know already that the answers to your leading questions are various varieties of "No". Scala handles overloading differently and, it must be admitted, somewhat less elegantly than you describe. Some of that's due to Java interoperability, some of that is due to not wanting to hit edged cases of the type inferencing algorithm, and some of that's due to it simply not being Haskell.
Adding to the already great answers here. Here's a gist that builds on Miles Sabin union types (and Josh's ideas) but also makes them recursively defined, so you can have >2 types in the union (def foo[A : UNil Or Int Or String Or List[String])
https://gist.github.com/aishfenton/2bb3bfa12e0321acfc904a71dda9bfbb
NB: I should add that after playing around with the above for a project, I ended up going back to plain-old-sum-types (i.e. sealed trait with subclasses). Miles Sabin union types are great for restricting the type parameter, but if you need to return a union type then it doesn't offer much.
In Scala 3, you can use Union types
Start a Scala 3 project: https://dotty.epfl.ch/#getting-started
One way is
sbt new lampepfl/dotty.g8
Then you can change directory to project, and type sbt console to start a REPL.
ref: https://dotty.epfl.ch/docs/reference/new-types/union-types.html
scala> def foo(xs: (Int | String)*) = xs foreach {
| case _: String => println("str")
| case _: Int => println("int")
| }
def foo(xs: (Int | String)*): Unit
scala> foo(2,"2","acc",-223)
int
str
str
int
From the docs, with the addition of sealed:
sealed class Expr
case class Var (x: String) extends Expr
case class Apply (f: Expr, e: Expr) extends Expr
case class Lambda(x: String, e: Expr) extends Expr
Regarding the sealed part:
It is possible to define further case classes that extend type Expr in other parts of the program (...). This form of extensibility can be excluded by declaring the base class Expr sealed; in this case, all classes that directly extend Expr must be in the same source file as Expr.

What's the relationship between PartialFunction and Function1

I'm learning Scala, and find from scala doc the definition of PartialFunction and Function1, as shown below:
trait PartialFunction[-A, +B] extends (A) ⇒ B
trait Function1[-T1, +R] extends AnyRef
Q1) My 1st question is: what's the type of (A) => B?
And, I know we can turn the PartialFunction to be a normal function by the lift method.
But Q2) what's the relationship between ParitialFunction and Function1?
It seems if some function parameter is of type Function1, we can pass a matching PartitionFunction to it, as shown below:
scala> val process = (f: Function1[String, Int]) => f("1024")
process: (String => Int) => Int = <function1>
scala> val pattern = "([0-9]+)".r
pattern: scala.util.matching.Regex = ([0-9]+)
scala> val str2int: PartialFunction[String, Int] = {
| case pattern(num) => num.toInt
| }
str2int: PartialFunction[String,Int] = <function1>
scala> accept(str2int)
res67: Int = 1024
Thanks!
A ⇒ B is syntax sugar for Function1[A, B]. Similarly, (A1, A2) ⇒ R is actually Function2[A1, A2, R], etc. all the way to 22 (completely arbitrary limit). The definition of PartialFunction is thus
trait PartialFunction[-A, +B] extends Function1[A, B]
Since a PartialFunction[A, B] is also a Function1[A, B], you can pass it into something that wants an A ⇒ B. The only reason we use ⇒ over FunctionN is aesthetic: it looks nicer. Indeed, since ⇒ isn't really a type name, we can't say something like:
type ApIntInt[T[_, _]] = T[Int, Int]
// ApIntInt[⇒] // Error: ⇒ is not a type and was not expected here
ApIntInt[Function1] // Fine: Function1 is a type, it has the right kind, so it works.
// ApIntInt[Function1] = Function1[Int, Int] = Int ⇒ Int
Since you're a beginner, you won't see this kind of stuff (higher kinds) for a long time yet, but it is there, and you may well hit it someday.
When you use a PartialFunction as a Function1, if you pass a value at which it is not defined, it (probably) throws an exception, which is usually a MatchError (but doesn't have to be). By contrast, if you call pf.lift, that creates a Function[In, Option[Out]], which returns Some(result) if the PartialFunction is defined at a point, and returns None if it isn't, per the Scaladoc.
Ex:
lazy val factorial: PartialFunction[Int, Int] = {
case num if num > 1 => num * factorial(num - 1)
case 1 => 1
}
assert(!factorial.isDefinedAt(0))
factorial.apply(0) // Using a PF as a Function1 on an undefined point breaks (here with MatchError)
factorial.lift.apply(0) // This just returns None, because it checks isDefinedAt first

How to know if an object is an instance of a TypeTag's type?

I have a function which is able to know if an object is an instance of a Manifest's type. I would like to migrate it to a TypeTag version. The old function is the following one:
def myIsInstanceOf[T: Manifest](that: Any) =
implicitly[Manifest[T]].erasure.isInstance(that)
I have been experimenting with the TypeTags and now I have this TypeTag version:
// Involved definitions
def myInstanceToTpe[T: TypeTag](x: T) = typeOf[T]
def myIsInstanceOf[T: TypeTag, U: TypeTag](tag: TypeTag[T], that: U) =
myInstanceToTpe(that) stat_<:< tag.tpe
// Some invocation examples
class A
class B extends A
class C
myIsInstanceOf(typeTag[A], new A) /* true */
myIsInstanceOf(typeTag[A], new B) /* true */
myIsInstanceOf(typeTag[A], new C) /* false */
Is there any better way to achieve this task? Can the parameterized U be omitted, using an Any instead (just as it is done in the old function)?
If it suffices to use subtyping checks on erased types, do as Travis Brown suggested in the comment above:
def myIsInstanceOf[T: ClassTag](that: Any) =
classTag[T].runtimeClass.isInstance(that)
Otherwise you need to explicitly spell out the U type, so that scalac captures its type in a type tag:
def myIsInstanceOf[T: TypeTag, U: TypeTag] =
typeOf[U] <:< typeOf[T]
In your specific case, if you actually need to migrate existing code and keep the same behavior, you want ClassTag. Using TypeTag is more precise, but exactly because of that some code is going to behave differently, so (in general) you need to be careful.
If you indeed want TypeTag, we can do even better than the above syntax; the effect at the call site is the same as omitting U.
Recommended alternatives
Using pimping
With Eugene's answer, one has to spell both types, while it's desirable to deduce the type of that. Given a type parameter list, either all or none are specified; type currying could maybe help, but it seems simpler to just pimp the method. Let's use for this implicit classes, also new in 2.10, to define our solution in just 3 lines.
import scala.reflect.runtime.universe._
implicit class MyInstanceOf[U: TypeTag](that: U) {
def myIsInstanceOf[T: TypeTag] =
typeOf[U] <:< typeOf[T]
}
I would in fact argue that something like this, with a better name (say stat_isInstanceOf), could even belong into Predef.
Use examples:
//Support testing (copied from above)
class A
class B extends A
class C
//Examples
(new B).myIsInstanceOf[A] //true
(new B).myIsInstanceOf[C] //false
//Examples which could not work with erasure/isInstanceOf/classTag.
List(new B).myIsInstanceOf[List[A]] //true
List(new B).myIsInstanceOf[List[C]] //false
//Set is invariant:
Set(new B).myIsInstanceOf[Set[A]] //false
Set(new B).myIsInstanceOf[Set[B]] //true
//Function1[T, U] is contravariant in T:
((a: B) => 0).myIsInstanceOf[A => Int] //false
((a: A) => 0).myIsInstanceOf[A => Int] //true
((a: A) => 0).myIsInstanceOf[B => Int] //true
A more compatible syntax
If pimping is a problem because it changes the invocation syntax and you have existing code, we can try type currying (more tricky to use) as follows, so that just one type parameter has to be passed explicitly - as in your old definition with Any:
trait InstanceOfFun[T] {
def apply[U: TypeTag](that: U)(implicit t: TypeTag[T]): Boolean
}
def myIsInstanceOf[T] = new InstanceOfFun[T] {
def apply[U: TypeTag](that: U)(implicit t: TypeTag[T]) =
typeOf[U] <:< typeOf[T]
}
myIsInstanceOf[List[A]](List(new B)) //true
If you want to learn to write such code yourself, you might be interested in the discussion of variations shown below.
Other variations and failed attempts
The above definition can be made more compact with structural types:
scala> def myIsInstanceOf[T] = new { //[T: TypeTag] does not give the expected invocation syntax
def apply[U: TypeTag](that: U)(implicit t: TypeTag[T]) =
typeOf[U] <:< typeOf[T]
}
myIsInstanceOf: [T]=> Object{def apply[U](that: U)(implicit evidence$1: reflect.runtime.universe.TypeTag[U],implicit t: reflect.runtime.universe.TypeTag[T]): Boolean}
Using structural types is however not always a good idea, as -feature warns:
scala> myIsInstanceOf[List[A]](List(new B))
<console>:14: warning: reflective access of structural type member method apply should be enabled
by making the implicit value language.reflectiveCalls visible.
This can be achieved by adding the import clause 'import language.reflectiveCalls'
or by setting the compiler option -language:reflectiveCalls.
See the Scala docs for value scala.language.reflectiveCalls for a discussion
why the feature should be explicitly enabled.
myIsInstanceOf[List[A]](List(new B))
^
res3: Boolean = true
The problem is the slowdown due to reflection, required to implement structural types. Fixing it is easy, just makes the code a bit longer, as seen above.
A pitfall I had to avoid
In the above code, I write [T] instead of [T: TypeTag], my first attempt. It is interesting why it fails. To understand that, take a look:
scala> def myIsInstanceOf[T: TypeTag] = new {
| def apply[U: TypeTag](that: U) =
| typeOf[U] <:< typeOf[T]
| }
myIsInstanceOf: [T](implicit evidence$1: reflect.runtime.universe.TypeTag[T])Object{def apply[U](that: U)(implicit evidence$2: reflect.runtime.universe.TypeTag[U]): Boolean}
If you look carefully at the type of the return value, you can see it's implicit TypeTag[T] => U => implicit TypeTag[U] (in pseudo-Scala notation). When you pass an argument, Scala will think it's for the first parameter list, the implicit one:
scala> myIsInstanceOf[List[A]](List(new B))
<console>:19: error: type mismatch;
found : List[B]
required: reflect.runtime.universe.TypeTag[List[A]]
myIsInstanceOf[List[A]](List(new B))
^
A tip
Last and least, one tip which might or not interest you: in this attempt, you are passing TypeTag[T] twice - hence you should remove : TypeTag after [T.
def myIsInstanceOf[T: TypeTag, U: TypeTag](tag: TypeTag[T], that: U) =
myInstanceToTpe(that) stat_<:< tag.tpe
I used the above suggestions to come up with the following. Feedback is welcomed.
/*
Attempting to cast Any to a Type of T, using TypeTag
http://stackoverflow.com/questions/11628379/how-to-know-if-an-object-is-an-instance-of-a-typetags-type
*/
protected def toOptInstance[T: ClassTag](any: Any) =
classTag[T].runtimeClass.isInstance(any) match {
case true =>
Try(any.asInstanceOf[T]).toOption
case false =>
/*
Allow only primitive casting
*/
if (classTag[T].runtimeClass.isPrimitive)
any match {
case u: Unit =>
castIfCaonical[T](u, "void")
case z: Boolean =>
castIfCaonical[T](z, "boolean")
case b: Byte =>
castIfCaonical[T](b, "byte")
case c: Char =>
castIfCaonical[T](c, "char")
case s: Short =>
castIfCaonical[T](s, "short")
case i: Int =>
castIfCaonical[T](i, "int")
case j: Long =>
castIfCaonical[T](j, "long")
case f: Float =>
castIfCaonical[T](f, "float")
case d: Double =>
castIfCaonical[T](d, "double")
case _ =>
None
}
else None
}
protected def castIfCaonical[T: ClassTag](value: AnyVal, canonicalName: String): Option[T] ={
val trueName = classTag[T].runtimeClass.getCanonicalName
if ( trueName == canonicalName)
Try(value.asInstanceOf[T]).toOption
else None
}
You can also capture type from TypeTag (into type alias), but only if it's not erased, so it will not work inside function:
How to capture T from TypeTag[T] or any other generic in scala?

What are type lambdas in Scala and what are their benefits?

Sometime I stumble into the semi-mysterious notation of
def f[T](..) = new T[({type l[A]=SomeType[A,..]})#l] {..}
in Scala blog posts, which give it a "we used that type-lambda trick" handwave.
While I have some intutition about this (we gain an anonymous type parameter A without having to pollute the definition with it?), I found no clear source describing what the type lambda trick is, and what are its benefits. Is it just syntactic sugar, or does it open some new dimensions?
Type lambdas are vital quite a bit of the time when you are working with higher-kinded types.
Consider a simple example of defining a monad for the right projection of Either[A, B]. The monad typeclass looks like this:
trait Monad[M[_]] {
def point[A](a: A): M[A]
def bind[A, B](m: M[A])(f: A => M[B]): M[B]
}
Now, Either is a type constructor of two arguments, but to implement Monad, you need to give it a type constructor of one argument. The solution to this is to use a type lambda:
class EitherMonad[A] extends Monad[({type λ[α] = Either[A, α]})#λ] {
def point[B](b: B): Either[A, B]
def bind[B, C](m: Either[A, B])(f: B => Either[A, C]): Either[A, C]
}
This is an example of currying in the type system - you have curried the type of Either, such that when you want to create an instance of EitherMonad, you have to specify one of the types; the other of course is supplied at the time you call point or bind.
The type lambda trick exploits the fact that an empty block in a type position creates an anonymous structural type. We then use the # syntax to get a type member.
In some cases, you may need more sophisticated type lambdas that are a pain to write out inline. Here's an example from my code from today:
// types X and E are defined in an enclosing scope
private[iteratee] class FG[F[_[_], _], G[_]] {
type FGA[A] = F[G, A]
type IterateeM[A] = IterateeT[X, E, FGA, A]
}
This class exists exclusively so that I can use a name like FG[F, G]#IterateeM to refer to the type of the IterateeT monad specialized to some transformer version of a second monad which is specialized to some third monad. When you start to stack, these kinds of constructs become very necessary. I never instantiate an FG, of course; it's just there as a hack to let me express what I want in the type system.
The benefits are exactly the same as those conferred by anonymous functions.
def inc(a: Int) = a + 1; List(1, 2, 3).map(inc)
List(1, 2, 3).map(a => a + 1)
An example usage, with Scalaz 7. We want to use a Functor that can map a function over the second element in a Tuple2.
type IntTuple[+A]=(Int, A)
Functor[IntTuple].map((1, 2))(a => a + 1)) // (1, 3)
Functor[({type l[a] = (Int, a)})#l].map((1, 2))(a => a + 1)) // (1, 3)
Scalaz provides some implicit conversions that can infer the type argument to Functor, so we often avoid writing these altogether. The previous line can be rewritten as:
(1, 2).map(a => a + 1) // (1, 3)
If you use IntelliJ, you can enable Settings, Code Style, Scala, Folding, Type Lambdas. This then hides the crufty parts of the syntax, and presents the more palatable:
Functor[[a]=(Int, a)].map((1, 2))(a => a + 1)) // (1, 3)
A future version of Scala might directly support such a syntax.
To put things in context: This answer was originally posted in another thread. You are seeing it here because the two threads have been merged. The question statement in the said thread was as follows:
How to resolve this type definition: Pure[({type ?[a]=(R, a)})#?] ?
What are the reasons of using such construction?
Snipped comes from scalaz library:
trait Pure[P[_]] {
def pure[A](a: => A): P[A]
}
object Pure {
import Scalaz._
//...
implicit def Tuple2Pure[R: Zero]: Pure[({type ?[a]=(R, a)})#?] = new Pure[({type ?[a]=(R, a)})#?] {
def pure[A](a: => A) = (Ø, a)
}
//...
}
Answer:
trait Pure[P[_]] {
def pure[A](a: => A): P[A]
}
The one underscore in the boxes after P implies that it is a type constructor takes one type and returns another type. Examples of type constructors with this kind: List, Option.
Give List an Int, a concrete type, and it gives you List[Int], another concrete type. Give List a String and it gives you List[String]. Etc.
So, List, Option can be considered to be type level functions of arity 1. Formally we say, they have a kind * -> *. The asterisk denotes a type.
Now Tuple2[_, _] is a type constructor with kind (*, *) -> * i.e. you need to give it two types to get a new type.
Since their signatures do not match, you cannot substitute Tuple2 for P. What you need to do is partially apply Tuple2 on one of its arguments, which will give us a type constructor with kind * -> *, and we can substitue it for P.
Unfortunately Scala has no special syntax for partial application of type constructors, and so we have to resort to the monstrosity called type lambdas. (What you have in your example.) They are called that because they are analogous to lambda expressions that exist at value level.
The following example might help:
// VALUE LEVEL
// foo has signature: (String, String) => String
scala> def foo(x: String, y: String): String = x + " " + y
foo: (x: String, y: String)String
// world wants a parameter of type String => String
scala> def world(f: String => String): String = f("world")
world: (f: String => String)String
// So we use a lambda expression that partially applies foo on one parameter
// to yield a value of type String => String
scala> world(x => foo("hello", x))
res0: String = hello world
// TYPE LEVEL
// Foo has a kind (*, *) -> *
scala> type Foo[A, B] = Map[A, B]
defined type alias Foo
// World wants a parameter of kind * -> *
scala> type World[M[_]] = M[Int]
defined type alias World
// So we use a lambda lambda that partially applies Foo on one parameter
// to yield a type of kind * -> *
scala> type X[A] = World[({ type M[A] = Foo[String, A] })#M]
defined type alias X
// Test the equality of two types. (If this compiles, it means they're equal.)
scala> implicitly[X[Int] =:= Foo[String, Int]]
res2: =:=[X[Int],Foo[String,Int]] = <function1>
Edit:
More value level and type level parallels.
// VALUE LEVEL
// Instead of a lambda, you can define a named function beforehand...
scala> val g: String => String = x => foo("hello", x)
g: String => String = <function1>
// ...and use it.
scala> world(g)
res3: String = hello world
// TYPE LEVEL
// Same applies at type level too.
scala> type G[A] = Foo[String, A]
defined type alias G
scala> implicitly[X =:= Foo[String, Int]]
res5: =:=[X,Foo[String,Int]] = <function1>
scala> type T = World[G]
defined type alias T
scala> implicitly[T =:= Foo[String, Int]]
res6: =:=[T,Foo[String,Int]] = <function1>
In the case you have presented, the type parameter R is local to function Tuple2Pure and so you cannot simply define type PartialTuple2[A] = Tuple2[R, A], because there is simply no place where you can put that synonym.
To deal with such a case, I use the following trick that makes use of type members. (Hopefully the example is self-explanatory.)
scala> type Partial2[F[_, _], A] = {
| type Get[B] = F[A, B]
| }
defined type alias Partial2
scala> implicit def Tuple2Pure[R]: Pure[Partial2[Tuple2, R]#Get] = sys.error("")
Tuple2Pure: [R]=> Pure[[B](R, B)]