| trait Functor[F[_]] | |
| object Functor { | |
| implicit val OptionFunctor: Functor[Option] = | |
| error("") | |
| } | |
| case class OptionT[F[+_], +A] | |
| object OptionT { | |
| implicit def OptionTFunctor[F[+_]](implicit F0: Functor[F]): Functor[({type λ[α] = OptionT[F, α]})#λ] = | |
| error("") | |
| } | |
| trait TTT { | |
| // fine | |
| val a = implicitly[Functor[Option]] | |
| // fine | |
| val b = implicitly[Functor[({type lam[+a]=OptionT[Option, a]})#lam]] | |
| // not fine | |
| val c = implicitly[Functor[({type lam[+a]=OptionT[({type l[+b]=OptionT[Option, b]})#l, a]})#lam]] | |
| } | |
This comment has been minimized.
This comment has been minimized.
|
I suspect it's to do with SLS §7.2 (p. 108), where the compiler is trying to avoid looping, but I'm not sure I'm understanding the spec correctly. Well, I'm also not sure the compiler understands the spec correctly, but that's another story... Suffice it to say:
|
This comment has been minimized.
This comment has been minimized.
|
The following seems to work:
Trying to replace, for example:
causes the world to explode:
This makes me believe that the way type lambdas are expressed as type refinements is running afoul of the definition of "core type." Again though, I don't really understand, this is just my most compelling hand-waving. |
This comment has been minimized.
This comment has been minimized.
|
Forget implicits for a moment; the problem is just type argument inference. case class Wibb[A]
trait Functor[F[_]]
object TTT {
val WibbFunctor: Functor[Wibb] =
error("")
def OptionTFunctor[F[_]](F0: Functor[F]): Functor[({type λ[α] = OptionT[F, α]})#λ] =
error("")
type S[A] = OptionT[({type l[b]=OptionT[Wibb, b]})#l, A]
// okay
OptionTFunctor[({type l[b]=OptionT[Wibb, b]})#l](OptionTFunctor[Wibb](WibbFunctor)): Functor[S]
// a bridge too far
OptionTFunctor(OptionTFunctor[Wibb](WibbFunctor)): Functor[S]
}
|
This comment has been minimized.
This comment has been minimized.
|
BTW, |
This comment has been minimized.
This comment has been minimized.
|
Thanks Jason, but why would out work with a type alias and not type lambda
inline? I struggle to how it would affect inferencing. I guess I can find
out with the compiler flag, thanks.
…On Jul 21, 2012 7:09 AM, "Jason Zaugg" < ***@***.***> wrote:
BTW, `-Yinfer-debug` is your friend at times like these.
---
Reply to this email directly or view it on GitHub:
https://gist.github.com/3148800
|
This comment has been minimized.
This comment has been minimized.
|
Oh, I missed the key point of your example. It's an interesting one. A bit of a closer look at it: case class Wibb[A]
trait Functor[F[_]]
object TTT {
implicit val WibbFunctor: Functor[Wibb] =
error("")
implicit def OptionTFunctor[F[_]](implicit F0: Functor[F]): Functor[({type λ[α] = OptionT[F, α]})#λ] =
error("")
type Q[A] = OptionT[Wibb, A]
type R[A] = OptionT[Q, A]
type S[A] = OptionT[({type l[b]=OptionT[Wibb, b]})#l, A]
// okay
OptionTFunctor[({type l[b]=OptionT[Wibb, b]})#l](OptionTFunctor[Wibb](WibbFunctor)): Functor[S]
OptionTFunctor[Q](OptionTFunctor(WibbFunctor)): Functor[R]
implicitly[Functor[R]] // Infers [Q] !
// a bridge too far
// OptionTFunctor(OptionTFunctor[Wibb](WibbFunctor)): Functor[S]
// Can't infer [Q]
// OptionTFunctor(OptionTFunctor(WibbFunctor)): Functor[R]
} |
This comment has been minimized.
This comment has been minimized.
|
Yeah, that's exactly the point. I will hopefully take a look at it closely soon. |
This comment has been minimized.