Skip to content

Flakey implicit resolution with type alias Id[A] = A #10238

@scabug

Description

@scabug

In the code below, implicit search for Monad[Id] succeeds by itself, but not always when it is part of a recursive search.

Most of the time it is impractical to define a type alias and annotate values with this type alias.

object Test {

  // Data types

  type Id[A] = A

  class MaybeT[F[_], A]

  type Maybe[A] = MaybeT[Id, A]

  type MaybeMaybe[A] = MaybeT[Maybe, A]


  // Typeclass

  trait Monad[F[_]]


  // Instances

  implicit val monadId: Monad[Id] = ???

  implicit def monadMaybeT[F[_]: Monad]: Monad[({ type λ[A] = MaybeT[F, A] })#λ] = ???

  implicit val monadOption: Monad[Option] = ???


  // Implicit search tests

  // OK
  implicitly[Monad[Id]]
  implicitly[Monad[({ type λ[A] = A })#λ]]

  // OK
  implicitly[Monad[Maybe]]

  // ERROR, despite asking for the same thing as before, but using a type lambda
  // error: could not find implicit value for parameter e: Test.Monad[[A]Test.MaybeT[[A]A,A]]
  implicitly[Monad[({ type λ[A] = MaybeT[Id, A] })#λ]]
  // implicitly[Monad[MaybeT[Id, ?]]]

  // OK
  implicitly[Monad[MaybeMaybe]]

  // ERROR, despite asking for the same thing as before, but using a type lambda
  // error: could not find implicit value for parameter e: Test.Monad[[A]Test.MaybeT[[A]Test.MaybeT[[A]A,A],A]]
  implicitly[Monad[({ type λ[A] = MaybeT[Maybe, A] })#λ]]
  // implicitly[Monad[MaybeT[Maybe, ?]]]

  // OK
  // Option instead of Maybe works,
  // because Option isn't a type alias containing Id.
  implicitly[Monad[({ type λ[A] = MaybeT[Option, A] })#λ]]
  // implicitly[Monad[MaybeT[Option, ?]]]
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions