Skip to content
No description, website, or topics provided.
Scala
Branch: master
Clone or download

Latest commit

Fetching latest commit…
Cannot retrieve the latest commit at this time.

Files

Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
project
src
.gitignore
.scalafmt.conf
.travis.yml
LICENSE
README.md
build.sbt
deploy.sbt.disabled
version.sbt

README.md

implicit-dependent-type

Join the chat at https://gitter.im/ThoughtWorksInc/implicit-dependent-type Build Status

implicit-dependent-type is a Scala compiler plugin that resolves dependent types from implicit type classes, especially useful when working with shapeless or other type-level programming libraries.

Setup

addCompilerPlugin("com.thoughtworks.implicit-dependent-type" %% "implicit-dependent-type" % "latest.release")

addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full)

libraryDependencies += "com.chuusai" %% "shapeless" % "latest.release"

Foo[Bar]##Baz syntax

This plugin provides a syntactic sugar that substitutes all Foo[Bar]##Baz with shapeless.the.`Foo[Bar]`.Baz, which inlines resolved implicit type classes into type declaration positions.

import shapeless._

final case class Foo(bar: Int, baz: String)

val hlistForFoo: Generic[Foo]##Repr = 1 :: "xxx" :: HNil
val foo: Foo = Generic[Foo].from(hlistForFoo)

The above example equals to the following code:

import shapeless._

final case class Foo(bar: Int, baz: String)

val g = Generic[Foo]
val hlistForFoo: g.Repr = 1 :: "xxx" :: HNil
val foo: Foo = Generic[Foo].from(hlistForFoo)

As you see, without this plugin, Generic[Foo] is not a stable value, thus it is unable to be placed at a type position. You will have to assign it to a temporary variable g.

This plugin resolves this problem.

Foo @Bar syntax (since 2.0)

Another syntactic sugar provided by this plugin is Foo @Bar, which will be converted to shapeless.the.`Bar[Foo]`.`@` .

For example:

trait GetElement[A] {
  type `@`
}

implicit def getArrayElement[Element] = new GetElement[Array[Element]] {
  override type `@` = Element
}

implicit def getSeqElement[Element] = new GetElement[Seq[Element]] {
  override type `@` = Element
}

val i: Array[Int] @GetElement = 1 // OK
val s: Seq[String] @GetElement = "text" // OK

val d: Option[Double] @GetElement = 0.5 // Does not compile because no implicit GetElement[Option[Double]] found

In the above example, @GetElement acts as a type level function, calculating the element type of the given type.

Note that the Foo @Bar syntax only applied if Bar starts with an upper case character. Thus, this plugin does not affect built-in annotations like @specialize, @cps or @suspendable because they start with a lower case character.

You can’t perform that action at this time.