Package

shapeless

compat

Permalink

package compat

Visibility
  1. Public
  2. All

Type Members

  1. trait Annotation[A, T] extends Serializable

    Permalink

    Evidence that type T has annotation A, and provides an instance of the annotation.

    Evidence that type T has annotation A, and provides an instance of the annotation.

    If type T has an annotation of type A, then an implicit Annotation[A, T] can be found, and its apply method provides an instance of the annotation.

    Example:

    case class First(i: Int)
    
    @First(3) trait Something
    
    
    val somethingFirst = Annotation[First, Something].apply()
    assert(somethingFirst == First(3))
  2. class AnnotationMacros extends CaseClassMacros

    Permalink
  3. trait Annotations[A, T] extends DepFn0 with Serializable

    Permalink

    Provides the annotations of type A of the fields or constructors of case class-like or sum type T.

    Provides the annotations of type A of the fields or constructors of case class-like or sum type T.

    If type T is case class-like, this type class inspects its fields and provides their annotations of type A. If type T is a sum type, its constructor types are looked for annotations.

    Type Out is an HList having the same number of elements as T (number of fields of T if T is case class-like, or number of constructors of T if it is a sum type). It is made of None.type (no annotation on corresponding field or constructor) and Some[A] (corresponding field or constructor is annotated).

    Method apply provides an HList of type Out made of None (corresponding field or constructor not annotated) or Some(annotation) (corresponding field or constructor has annotation annotation).

    Note that annotation types must be case class-like for this type class to take them into account.

    Example:

    case class First(s: String)
    
    case class CC(i: Int, @First("a") s: String)
    
    sealed trait Base
    @First("b") case class BaseI(i: Int) extends Base
    case class BaseS(s: String) extends Base
    
    
    val ccFirsts = Annotations[First, CC]
    val baseFirsts = Annotations[First, Base]
    
    // ccFirsts.Out is  None.type :: Some[First] :: HNil
    // ccFirsts.apply() is
    //   None :: Some(First("a")) :: HNil
    
    // baseFirsts.Out is  Some[First] :: None.type :: HNil
    // baseFirsts.apply() is
    //   Some(First("b")) :: None :: HNil
  4. final case class Cached[+T](value: T) extends AnyVal with Product with Serializable

    Permalink

    Wraps a cached implicit T.

    Wraps a cached implicit T.

    Looking for an implicit Cached[T] first triggers a look for an implicit T, caches the resulting tree, and returns it immediately and in subsequent look ups for an implicit Cached[T]. Thus, subsequent look ups do not trigger looking for an implicit T, only returning the instance kept in cache.

    Beware that if the contexts in which two subsequent look ups are different, so that looking for a T in each of them doesn't return the same result, this change would be ignored by caching. Looking for a Cached[T] in the first context would put the implicit T of this context in cache, and then looking for a Cached[T] in the second context would return the former instance from the first context. E.g.

    trait TC[T] {
      def msg: String
    }
    
    object First {
      implicit val tc: TC[Int] = new TC[Int] {
        val msg = "first"
      }
    
      def print() = println(implicitly[TC[Int]].msg)
      def printCached() = println(cached[TC[Int]].msg)
    }
    
    object Second {
      implicit val tc: TC[Int] = new TC[Int] {
        val msg = "second"
      }
    
      def print() = println(implicitly[TC[Int]].msg)
      def printCached() = println(cached[TC[Int]].msg)
    }
    
    First.print()
    Second.print()
    First.printCached()
    Second.printCached()

    would print "first" then "second" (non cached TC[Int] instances), then "first" twice (first instance, returned the second time too through the cache).

  5. class CachedMacros extends LazyMacros

    Permalink
  6. trait Default[T] extends DepFn0 with Serializable

    Permalink

    Provides default values of case class-like types.

    Provides default values of case class-like types.

    The Out type parameter is an HList type whose length is the number of fields of T. Its elements correspond to the fields of T, in their original order. It is made of None.type (no default value for this field) and Some[...] (default value available for this field, with ... the type of the field). Note that None.type and Some[...] are more precise than simply Option[...], so that the availability of default values can be used in type level calculations.

    The apply method returns an HList of type Out, with None elements corresponding to no default value available, and Some(defaultValue) to default value available for the corresponding fields.

    Use like

    case class CC(i: Int, s: String = "b")
    
    val default = Default[CC]
    
    // default.Out is  None.type :: Some[String] :: HNil
    
    // default() returns
    //   None :: Some("b") :: HNil,
    // typed as default.Out
  7. class DefaultMacros extends CaseClassMacros

    Permalink
  8. trait DerivationContext extends CaseClassMacros with LazyDefinitions

    Permalink
  9. trait Ignoring[M, T] extends AnyRef

    Permalink

    Allows to ignore some implicits in a LowPriority[T].

    Allows to ignore some implicits in a LowPriority[T].

    Use like LowPriority[Ignoring[Witness."ignoredMethod".T, T]].

    Typical usage is when a fallback for type class TC is defined in its companion, like

    object TC {
      implicit def anyTC[T]: TC[T] = ...
    }

    With the example of LowPriority[T] above,

    trait TC[T] {
      def prop: Option[Boolean]
    }
    
    trait LowPriTC {
      // default low priority TC[T] for any T, with field `prop` equal to `None`
      implicit def anyTC[T]: TC[T] = new TC[T] { def prop = None }
    }
    
    object TC extends LowPriTC {
      // TC[Int] available by default, with field `prop` equal to `Some(true)`
      implicit val intTC: TC[Int] = new TC[Int] { def prop = Some(true) }
    }
    
    // extra `TC[T]`, with field `prop` equal to `Some(false)`
    implicit def extraTC[T](implicit ev: LowPriority[Ignoring[Witness.`"anyTC"`.T, TC[T]]]): TC[T] =
      new TC[T] { def prop = Some(false) }
    
    // Already available instance `intTC` is still found, because `extraTC[Int]` requires a
    // `LowPriority[TC[Int]]`, that will refuse to materialize (because `LowPriority` is able to
    // know about the already available `intTC`.)
    assert(implicitly[TC[Int]].prop == true)
    
    // `extraTC[String]` is found, as the default `anyTC[String]` is ignored,
    assert(implicitly[TC[String]].prop == false)
  10. class IllTypedMacros extends AnyRef

    Permalink
  11. trait Lazy[+T] extends Serializable

    Permalink

    Wraps a lazily computed value.

    Wraps a lazily computed value. Also circumvents cycles during implicit search, or wrong implicit divergences as illustrated below, and holds the corresponding implicit value lazily.

    The following implicit search sometimes fails to compile, because of a wrongly reported implicit divergence,

    case class ListCC(list: List[CC])
    case class CC(i: Int, s: String)
    
    trait TC[T]
    
    object TC {
      implicit def intTC: TC[Int] = ???
      implicit def stringTC: TC[String] = ???
      implicit def listTC[T](implicit underlying: TC[T]): TC[List[T]] = ???
    
      implicit def genericTC[F, G](implicit
        gen: Generic.Aux[F, G],
        underlying: TC[G]
      ): TC[F] = ???
    
      implicit def hnilTC: TC[HNil] = ???
    
      implicit def hconsTC[H, T <: HList](implicit
        headTC: TC[H],
        tailTC: TC[T]
      ): TC[H :: T] = ???
    }
    
    implicitly[TC[CC]] // fails with: diverging implicit expansion for type TC[CC]

    This wrongly reported implicit divergence can be circumvented by wrapping some of the implicit values in Lazy,

    case class ListCC(list: List[CC])
    case class CC(i: Int, s: String)
    
    trait TC[T]
    
    object TC {
      implicit def listTC[T](implicit underlying: TC[T]): TC[List[T]] = ???
    
      implicit def genericTC[F, G](implicit
        gen: Generic.Aux[F, G],
        underlying: Lazy[TC[G]] // wrapped in Lazy
      ): TC[F] = ???
    
      implicit def hnilTC: TC[HNil] = ???
    
      implicit def hconsTC[H, T <: HList](implicit
        headTC: Lazy[TC[H]], // wrapped in Lazy
        tailTC: TC[T]
      ): TC[H :: T] = ???
    }
    
    implicitly[TC[CC]]

    When looking for an implicit Lazy[TC[T]], the Lazy.mkLazy macro will itself trigger the implicit search for a TC[T]. If this search itself triggers searches for types wrapped in Lazy, these will be done only once, their result put in a lazy val, and a reference to this lazy val will be returned as the corresponding value. It will then wrap all the resulting values together, and return a reference to the first one.

    E.g. with the above example definitions, when looking up for an implicit TC[CC], the returned tree roughly looks like

    TC.genericTC(
      Generic[CC], // actually, the tree returned by Generic.materialize, not written here for the sake of brevity
      Lazy {
        lazy val impl1: TC[List[CC] :: HNil] = TC.hconsTC(
          Lazy(impl2),
          TC.hnilTC
        )
        lazy val impl2: TC[List[CC]] = TC.listTC(TC.genericTC(
          Generic[CC], // actually, the tree returned by Generic.materialize
          Lazy(impl1)  // cycles to the initial TC[List[CC] :: HNil]
        ))
    
        impl1
      }
    )
  12. trait LazyDefinitions extends AnyRef

    Permalink
  13. trait LazyExtension extends AnyRef

    Permalink
  14. trait LazyExtensionCompanion extends AnyRef

    Permalink

    Lazy extension companions should extend this trait, and return a new LazyExtension instance via instantiate.

    Lazy extension companions should extend this trait, and return a new LazyExtension instance via instantiate.

    These companions typically provide a materializer method like

    implicit def init[H]: Wrapper[T] = macro initImpl

    , where Wrapper is the wrapper type that this extension handles, and initImpl is provided by the LazyExtensionCompanion trait. This initializes the extension upon first use during a Lazy / Strict implicit search.

  15. class LazyMacros extends AnyRef

    Permalink
  16. trait LowPriority[T] extends Serializable

    Permalink

    Evidence that no implicit T instance is available elsewhere.

    Evidence that no implicit T instance is available elsewhere.

    The instance using the LowPriority[T] is ignored.

    Allows to prioritize implicits, for example

    trait TC[T] {
      def prop: Boolean
    }
    
    object TC {
      // TC[Int] available by default, with field `prop` true
      implicit val intTC: TC[Int] = new TC[Int] { def prop = true }
    }
    
    // extra `TC[T]`, with field `prop` false
    implicit def extraTC[T](implicit ev: LowPriority[TC[T]]): TC[T] =
      new TC[T] { def prop = false }
    
    // Already available instance `intTC` is still found, because `extraTC[Int]` requires a
    // `LowPriority[TC[Int]]`, that will refuse to materialize (because `LowPriority` is able to
    // know about the already available `intTC`.)
    assert(implicitly[TC[Int]].prop == true)
    
    // `extraTC[String]` is found, as no other `TC[String]` can be found elsewhere
    assert(implicitly[TC[String]].prop == false)
  17. trait LowPriorityExtension extends LazyExtension with LowPriorityTypes

    Permalink
  18. trait LowPriorityTypes extends AnyRef

    Permalink
  19. trait Strict[+T] extends Serializable

    Permalink

    Wraps an eagerly computed value.

    Wraps an eagerly computed value. Prevents wrongly reported implicit divergence, like Lazy does, but, unlike it, does not circumvent implicit cycles.

    Creation of Lazy instances usually triggers the creation of an anonymous class, to compute the wrapped value (e.g. with the by-name argument of Lazy.apply). Strict avoids that, which can lead to less overhead during compilation.

  20. trait Widen[T] extends DepFn1[T]

    Permalink
  21. class WidenMacros extends SingletonTypeUtils

    Permalink

Value Members

  1. object Annotation extends Serializable

    Permalink
  2. object Annotations extends Serializable

    Permalink
  3. object Cached extends Serializable

    Permalink
  4. object CachedMacros

    Permalink
  5. object Default extends Serializable

    Permalink
  6. object DerivationContext

    Permalink
  7. object IllTyped

    Permalink

    A utility which ensures that a code fragment does not typecheck.

    A utility which ensures that a code fragment does not typecheck.

    Credit: Stefan Zeiger (@StefanZeiger)

  8. object Lazy extends Serializable

    Permalink
  9. object LazyMacros

    Permalink
  10. object LowPriority extends LazyExtensionCompanion with Serializable

    Permalink
  11. object Strict extends Serializable

    Permalink
  12. object Widen

    Permalink
  13. object lazily

    Permalink

Ungrouped