Partially applying type parameters - scala

I'm desperately trying to solve the following:
trait Access[Res[_]] { def access[C]: Res[C] }
trait CList[C1, A] extends Access[CList[_, A]] // ?!
def test[C1, C2, A](c: CList[C1, A]): CList[C2, A] = c.access[C2]
scalac just says: "error: illegal cyclic reference involving trait CList". how can I make this compile?

You might be interested in type lambdas. The partial application you used in your answer is actually implemented in scalaz.
As the code tends to get less readable though, they started using type lambdas instead. The type in question could be written as
({type λ[α] = CList[α,A]})#λ
This works by creating a type projection on a parameterized type λ inside a structural type thus capturing the outer type parameter (in this case A).
The other problem concerning variance described in your answer could be solved by making the Res parameter in Access covariant.
After these changes your code should look like this:
trait Access[+Res[_]] { def access[C] : Res[C]}
trait CList[C, +A] extends Access[({type λ[α] = CList[α,A]})#λ]

googling for "partial type application" i found this solution posted by James Iry on the scala debate list ( http://scala-programming-language.1934581.n4.nabble.com/Partial-type-inference-td2007311.html ; adapted so the arg order is changed):
type Partial2[T[_,_], B] = {
type Apply[A] = T[A,B]
}
trait CList[C1, A] extends Access[Partial2[CList, A]#Apply]
cheese louise, is this really the only way to do that in scala in 2011 ?!!
EDIT:
This fails with covariance in A :,-(
trait Access[Res[_]] { def access[C]: Res[C] }
type Partial2[T[_,_], B] = {
type Apply[A] = T[A,B]
}
trait CList[C1, +A] extends Access[Partial2[CList, A]#Apply]
"covariant type A occurs in invariant position"

Just to update things
add this compiler plugin to your sbt for kind projection and you'll get a nice syntax using ?. This removes the type projection boilerplate which looks messy!
So you can write stuff like Either[String, ?]
addCompilerPlugin("org.spire-math" %% "kind-projector" % "0.9.7")
it's implemented with the same old type projection underneath
You can also find it here: https://underscore.io/blog/posts/2016/12/05/type-lambdas.html

I know this is a really old question, but anyway:
trait AnyAccess {
type Res[X]
def access[Z]: Res[Z]
}
trait AnyCList extends AnyAccess { me =>
type C
type A
// this could be a subtype bound instead, if needed
type Res[X] = AnyCList { type C = X; type A = me.A }
}
case object AnyCList {
type of[C0, +A0] = AnyCList { type C = C0; type A <: A0 }
}
case object buh {
def test[C1, C2, A](c: AnyCList.of[C1, A]): AnyCList.of[C2, A] = c.access[C2]
}

Here's a method that worked for me to "partially apply type parameters":
I had a function like
def foo[A, B, C, D, E](...)
Such that I needed to hint only one type parameter for the compiler to infer the rest. This worked for me:
object InferType {
type InferType[A] = Option[A]
def apply[A]: Option[A] = None
}
Update foo to take an additional parameter of type InferType:
// t parameter is unused in implementation but
// is used by compiler to infer other type parameters
def foo[A, B, C, D, E](..., t: InferType[D])
Usage:
foo(..., InferType[ConcreteD])

Related

How to get the parameter of a type constructor in Scala?

I'm looking for a way to "unwind" type aliases.
In the following example, only 'O' has a type alias defined in the second type aliasing line.
type CodebookDetails = List[(String, List[String])]
type O[I] = CodebookDetails
requestDecodeIterable[I, O](request)
Is it possible to get I in a similar way, or does one just have to copy and paste types like this?:
requestDecodeIterable[(String, List[String]), List](request)
You could use shapeless's the macro:
// Typelevel function unapplies unary type constructors:
// F[A] => (F, A)
// I think I recall seeing it somewhere in shapeless, but I can't find it,
// so I implemented it myself
sealed trait Unapp1[T] { type F[_]; type A; implicit def eq: F[A] =:= T }
object Unapp1 {
type Aux[T0, F0[_], A0] = Unapp1[T0] { type F[X] = F0[X]; type A = A0 }
implicit def source[F0[_], A0]: Aux[F0[A0], F0, A0] = new Unapp1[F0[A0]] {
type F[X] = F0[X]
type A = A0
override def eq: F[A] =:= F0[A0] = implicitly
}
def apply[T](implicit unapp: Unapp1[T]): unapp.type = unapp
}
// the.`tpe` looks up the implicit value of type tpe and gives it a stable path
// suitable for type selection
requestDecodeIterable[the.`Unapp1[CookbookDetails]`.A, the.`Unapp1[CookbookDetails]`.F](request)
It's not really an improvement in this case, especially because I think the inferencer can just do it itself, but it might have other uses.
EDIT: Found it: it's called Unpack1 in shapeless.

How to decompose a type constructor via implicits?

I have a class Foo that takes a type constructor F as type parameter:
case class Foo[F[_]](x: F[String])
Now I want to define a member method bar that is only applicable, if F[T] = Outer[Inner[T]] for some fixed outer type Outer, e.g. Option:
def bar[Inner[_]](implicit ev: ???): Foo[Inner]
The ??? must be something along a natural transformation F ~> Outer·Inner with · being composition of type constructors.
How does this implicit argument look like?
How can I get it from somewhere?
How to write type constructor composition?
Also how to best write composition of type constructors? I currently write using a type lambda ({type L[X] = Outer[Inner[X]]})#L.
Type equality for type constructors
I don't think there's one defined in ScalaZ, but it's fairly simple to make one, taking scalaz.Leibniz as a template. I won't focus on composition and convenience methods, and only get the substance:
sealed abstract class LeibnizK[F[_], G[_]] {
def subst[Z[_[_]]](p: Z[F]): Z[G]
}
object LeibnizK {
implicit def refl[F[_]] = new LeibnizK[F, F] {
override def subst[Z[_[_]]](p: Z[F]): Z[F] = p
}
}
Which seems to be the implicit you're looking for:
type Outer[A] = Option[A]
type Id[A] = A
case class Foo[F[_]](me: F[String]) {
// Oh boy, here comes type lambda
def bar[Inner[_]](implicit leibk: LeibnizK[
F,
({type L[A] = Outer[Inner[A]]})#L
]): Outer[Foo[Inner]] = leibk.subst(this).me.map(Foo(_)) // <- OK to use methods of Outer
}
assert(Foo[Option](Some("meh")).bar[Id] == Some(Foo[Id]("meh")))
ScalaFiddle
Better syntax for type composition
Check out kind projector compiler plugin. It allows you to write:
λ[A => Outer[Inner[A]]
// or
Lambda[A => Outer[Inner[A]]
instead of
({type L[A] = Outer[Inner[A]]})#L
And for simple cases (no nesting), there's even shorter syntax
(?, Int)
instead of
({type L[A] = (A, Int)})#L

Is it possible for Scala to infer types for Generic types passed into a dependent class?

Given the following:
trait A[X] {
def foo(): X
}
class B[T <: A[_]] {
def getFoo(a:T) = a.foo()
}
class C[T <: A[Z], Z] {
def getFoo(a:T):Z = a.foo()
}
Is it possible to make B work like C? Specifically getting the result type of a.foo().
scala> var b:B[A[Int]] = new B[A[Int]]()
scala> b.getFoo(AA(1))
res0: Any = 1
scala> var c:C[A[Int],Int] = new C[A[Int],Int]()
c: C[A[Int],Int] = C#4cc36c19
scala> c.getFoo(AA(1))
res1: Int = 1
b returns an Any, but c correctly returns an Int. This is obviously a contrived example, but it would greatly simplify by code if I could extract a subtype from a Generic type. Basically, knowing "Z" (as used in C) without having to pass it in explicitly - inferring from the type of A.
Obviously, C works as needed, but the issue is my framework is more akin to:
class D[T <: A[Z1], U <: B[Z2], Z1, Z2] extends E[T,U,Z1,Z2]
which then requires users of the framework to implement with 4 type parameters, when ideally it would only be 2
class D[T <: A[_], U <: B[_]] extends E[T,U]
Not a blocker, just an attempt at simplifying the exposed API.
You can do the following which is often used in certain typeclass based libraries:
trait Foo[H[_] <: Langh[_]]{
def thing[A](ha: H[A]): A = ha.ha()
}
This pushes the resolution of the type parameter to the invocation of the method thing. It uses higher-kinded types.
If fact, if you look at libs like ScalaZ, you'll see exactly this pattern:
trait Functor[F[_]]{
def map[A, B](fa: F[A])(f: A => B): F[B]
}
Reply to Comments
There is no way to have a type of U <: T[_] and then be able to extract out the type parameter of an actual T[A] because the very definition of it loses that information. If the above does not work for you, then I would suggest type classes:
trait Foo[U]{
def doStuff(u: U)(implicit ev: MyTypeClass[U]): ev.A = //...
}
wherein you only define your MyTypeClass implicits like the following:
trait Whatever[FA]{ /*...*/ }
object Whatever{
implicit def WhateverMTC[F[_] <: Bound[_], A0] = new MyTypeClass[F[A0]]{
type A = A0
//...
}
}
Then you can place your type bound on the implicit, your implicit carries with it the constraint that your type must be higher-kinded and you can get a method that returns the inner "hidden" type at the call site declaration.
That said, this is a lot of machinery when the first suggestion is much more elegant and a cleaner approach to the problem IMHO.

scala: overriding a value of generic, existential type with a concretised type

I have a generic trait MappingPath, invariant regarding it's type parameters:
trait MappingPath[X<:AnyMapping, Y<:AnyMapping]
and an interface of a factory for it:
trait Pathfinder[X, Y] {
def apply(fun :X=>Y) :MappingPath[_<:AnyMapping,_<:AnyMapping]
def get(fun :X=>Y) :Option[MappingPath[_<:AnyMapping, _<:AnyMapping]]
}
I start a skeleton implementation which works for a single mapping:
class MappingPathfinder[M<:AnyMapping, X, Y] extends Pathfinder[X, Y] {
override def apply(fun :X=>Y) :MappingPath[M, _<:AnyMapping] = ???
override def get(fun :X=>Y) :Option[MappingPath[M, _<:AnyMapping]] = ???
}
which produces a compile error complaining that MappingPathfinder.apply overrides nothing and doesn't implement Pathfinder.apply. What's interesting, replacing M with _<:AnyMapping in apply's return type makes it compile, and no complaints are made regarding similar get method.
What's going on? I use scala 2.11.5.
EDIT:
I was able to circumvene my problem by adding explicit existantial annotations:
//Pathfinder
def apply(fun :X=>Y) :MappingPath[A, B] forSome { type A<:AnyMapping; type B<:AnyMapping }
//MappingPathfinder
def apply(fun :X=>Y) :MappingPath[A, B] forSome { type A>:M<:M; type B<:AnyMapping }
It seems to work, i.e
I can do:
(p :MappingPath[_<:AnyMapping, M]) ++ mappingPathfinder(f),
where ++ requires a path starting with the exact same type as this ends. It looks a bit silly and certainly confusing though.
Not an answer, but your use case can be simplified to:
trait Higher[U]
trait Super {
def foo: Higher[_]
}
trait Sub[M] {
override def foo: Higher[M] // error: method foo overrides nothing
}
Instead of existential types, I would use a type member:
trait Super {
type U
def foo: Higher[U]
}
trait Sub[M] {
type U = M
}
I think the difference is that in the case of the existential type, you only specify that the type parameter returned has some upper bound, but not necessarily that it is always the same type; whereas in my second example, type U means this will eventually be one specific type, and you can only refine a specific type. You can make upper bounds more precise:
trait Upper
trait A {
type U <: Upper
}
trait Specific extends Upper
trait B extends A {
type U <: Specific // type is "overridden"
}
If it's possible, I would avoid existential types, and your case seems a perfect fit for such avoidance. Most of the time, existential types are only needed for Java interop.

Overriding abstract type does not work with control abstraction

This question follows the one in Cake pattern with overriding abstract type don't work with Upper Type Bounds. I want to override the abstract type in trait with <:. The previous links gives the solution which consists in changing the order of linearization by writting this: Cake with S in trait S. However, I added a control abstraction named control in the following code. I want to call the method t in it.
trait A {
def ping = println("ping")
}
trait Cake {
type T
}
trait S { this: Cake with S =>
type T <: A with S
def t: T
def s = println("test")
// def control(c: =>T): T = c // compile
// def control(c: =>T): T = c.s // does not compile
def control(c: =>T): T = c.t // does not compile
t.ping
t.s
}
But, this code results in a compilation error that I can't explain
found : S.this.T#T
required: S.this.T
def control(c: =>T): T = c.t
^
What is wrong ?
def control(c: =>T): T
Has return type S#T. Clearly, c has type T as well. Hence, returning c in:
def control(c: =>T): T = c
compiles, while returning c.s does not compile because s has return type of Unit.
c.t does not compile because it has return type of S#T#T.
Thus, the following will compile:
def control(c: =>T): T#T = c.t
As the specifics behind everything that is happening here are a bit non-trivial in general, I suggest you google "type projection" and "path dependent types" for more information.
Essentially what is happening is c has type T, where T <: A with S, so we know T must have all of S's members, one of which is defined as def t: T. But this T is not necessarily the same as our T, so it does not conform when we call c.t in your example. What we want is the T of type T (or equivalently, T's T, or the T of our type member T). Here T#T indicates exactly what we want.