https://github.com/thoughtworksinc/implicit-dependent-type
https://github.com/thoughtworksinc/implicit-dependent-type
Last synced: 8 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/thoughtworksinc/implicit-dependent-type
- Owner: ThoughtWorksInc
- License: apache-2.0
- Created: 2016-12-26T06:54:32.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2017-11-08T07:52:12.000Z (about 8 years ago)
- Last Synced: 2025-04-05T21:51:14.969Z (9 months ago)
- Language: Scala
- Size: 37.1 KB
- Stars: 22
- Watchers: 29
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
[](https://gitter.im/ThoughtWorksInc/implicit-dependent-type?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](https://travis-ci.org/ThoughtWorksInc/implicit-dependent-type)
**implicit-dependent-type** is a Scala compiler plugin that resolves dependent types from implicit type classes,
especially useful when working with [shapeless](https://github.com/milessabin/shapeless) or other type-level programming libraries.
## Setup
``` sbt
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.
``` scala
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:
``` scala
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:
``` scala
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.