I want to do something like this:
def fold[C[A]](implicit ev: Foldable[A]): A
I am getting not found: type A
I know, I can do this instead:
def fold[C[_], A: Foldable]: A
But, I would rather invoke as fold[List[Int]]
than fold[List, Int]
I played a bit with it and came up with a helper type class:
trait Helper[M[_], CA] {
type C[_]
type A
implicit def ma: M[A]
}
object Helper {
implicit def instance[M0[_], C0[_], A0](implicit ma0: M0[A0]) = new Helper[M0, C0[A0]] {
type C[X] = C0[X]
type A = A0
val ma: M0[A0] = ma0
}
}
I know the names are pretty generic, I'd suggest finding more meaningful names.
Now instead of requiring an implicit of type Foldable[A]
you require instead an implicit of Helper[Foldable, CA]
where CA
is the type that must match against List[Int]
in your example:
def fold[CA](implicit helper: Helper[Foldable, CA]): helper.A
As an example:
def fold[CA](implicit helper: Helper[Foldable, CA]): helper.A = {
import helper._
println(implicitly[Foldable[A]])
null.asInstanceOf[A]
}
scala> :paste
// Entering paste mode (ctrl-D to finish)
case class Foldable[A](name: String)
implicit val stringFoldable = Foldable[String]("String")
implicit val intFoldable = Foldable[Int]("Int")
implicit val floatFoldable = Foldable[Float]("Float")
def fold[CA](implicit helper: Helper[Foldable, CA]): helper.A = {
import helper._
println(implicitly[Foldable[A]])
null.asInstanceOf[A]
}
// Exiting paste mode, now interpreting.
defined class Foldable
stringFoldable: Foldable[String] = Foldable(String)
intFoldable: Foldable[Int] = Foldable(Int)
floatFoldable: Foldable[Float] = Foldable(Float)
fold: [CA](implicit helper: Helper[Foldable,CA])helper.A
scala> fold[List[String]]
Foldable(String)
res0: String = null
scala> fold[List[Int]]
Foldable(Int)
res1: Int = 0
scala> fold[List[Float]]
Foldable(Float)
res2: Float = 0.0
Here's what I came up with:
trait Foo[T, A]
implicit def makeFoo[A, M[_]] = new Foo[M[A], A] {}
class Helper[T] {
def apply[A]()(implicit ev: Foo[T, A]) = ev
}
def bar[T] = new Helper[T]
bar[List[Int]]()
//Foo[List[Int],Int] = $anon$1@7edf6563
The empty pair of parens might not be ideal if you really want an a no-arg method, but I can't see how to get around that at the moment.
fold
useful without something to fold? Two type parameters is fine when you can rely on type inference:def fold[A: Foldable, C[_]](ca: C[A]) = ???
– Michael Zajacfold
withfooBar
– pathikritC[A]
which would allow you to infer the type parameters rather than supplying them manually. In other words, I'm pretty sure there is no way to achieve what you ask with only one type parameter. – Michael ZajacSince the names of higher-order type parameters are thus often irrelevant, they may be denoted with a ‘_’, which is nowhere visible.
scala-lang.org/files/archive/spec/2.11/… – som-snytt