Skip to content

Commit

Permalink
Fix annotations being passed from trait to generated companion
Browse files Browse the repository at this point in the history
  • Loading branch information
lloydmeta committed May 19, 2017
1 parent d29d57f commit e030509
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 65 deletions.
38 changes: 22 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ The `@diesel` annotation that cuts out the boilerplate associated with writing c
The Dsl can be accessed directly from the companion object if you import a converter located in `ops`
(customisable by passing a name to the annotation as an argument). This are useful when you need to compose multiple DSLs in the context of `F[_]`, but do not want to name all the interpreter parameters.

Note that this can be used along-side `@ktrans`.

### Example:

```scala
Expand All @@ -26,8 +28,8 @@ object DieselDemo {
// Declare your DSL
@diesel
trait Maths[F[_]] {
def int(i: Int): F[Int]
def add(l: F[Int], r: F[Int]): F[Int]
def times(l: Int, r: Int): F[Int]
def add(l: Int, r: Int): F[Int]
}

@diesel
Expand All @@ -37,32 +39,34 @@ object DieselDemo {

// Import companion-to-interpreter aliasing sugar
import Maths.ops._, Logger.ops._
def addAndLog[F[_]: Monad: Maths: Logger](x: Int, y: Int): F[Int] = {
def prog[F[_]: Monad: Maths: Logger](x: Int, y: Int): F[Int] = {
for {
r <- Maths.add(Maths.int(x), Maths.int(y))
_ <- Logger.info(s"result $r")
} yield r
p <- Maths.times(x, y)
_ <- Logger.info(s"Product: $p")
s <- Maths.add(x, y)
_ <- Logger.info(s"Sum: $s")
} yield p + s
}

def main(args: Array[String]): Unit = {

// Wire in our interpreters
implicit val mathsInterp = new Maths[Id] {
def int(a: Int) = a
def add(a: Id[Int], b: Id[Int]) = a + b
def times(l: Int, r: Int) = l * r
def add(l: Int, r: Int) = l + r
}
implicit val loggingInterp = new Logger[Id] {
def info(msg: String) = println(msg)
}

addAndLog[Id](1, 2)
()
val _ = prog[Id](1, 2)
}

}
/*
[info] Running DieselDemo
result 3
Product: 2
Sum: 3
*/
```

Expand All @@ -79,8 +83,8 @@ All of the above examples use a pure KVS interpreter :)
```scala
@diesel
trait Maths[F[_]] {
def int(i: Int): F[Int]
def add(l: F[Int], r: F[Int]): F[Int]
def times(l: Int, r: Int): F[Int]
def add(l: Int, r: Int): F[Int]
}
```

Expand All @@ -89,8 +93,8 @@ is expanded approximately into
```scala
// Your algebra. Implement by providing a concrete F and you have your interpreter
trait Maths[F[_]] {
def int(i: Int): F[Int]
def add(l: F[Int], r: F[Int]): F[Int]
def times(l: Int, r: Int): F[Int]
def add(l: Int, r: Int): F[Int]
}

// Helper methods will be added to the algebra's companion object (one will be created if there isn't one yet)
Expand All @@ -111,7 +115,9 @@ object Maths {

There is also a handy `@ktrans` annotation that adds a `transformK` method to a trait that is parameterised by a Kind that
takes 1 type parameter. It's useful when you want to transform any given implementation of that trait for `F[_]` into one
that implements it on `G[_]`
that implements it on `G[_]`.

Note that this can be used along-side `@diesel`.

### Example

Expand Down
4 changes: 3 additions & 1 deletion core/src/main/scala/diesel/diesel.scala
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import scala.annotation.compileTimeOnly
* | // Declare our DSL
* | @diesel
* | trait Maths[G[_]] {
* | def times(l: Int, r: Int): G[Int]
* | def add(l: Int, r: Int): G[Int]
* | }
* | @diesel
Expand All @@ -39,7 +40,8 @@ import scala.annotation.compileTimeOnly
* | }
*
* scala> implicit val MathsIdInterp = new Maths[Id] {
* | def add(l: Int, r: Int) = l + r
* | def times(l: Int, r: Int) = l * r
* | def add(l: Int, r: Int) = l + r
* | }
*
* scala> implicit val LoggerIdInterp = new Logger[Id] {
Expand Down
5 changes: 3 additions & 2 deletions core/src/main/scala/diesel/internal/DieselImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ object DieselImpl {
Term.Block(
Seq(
extracted.underlying,
q"""..${objectModsOnly(mods)} object ${Term.Name(tname.value)} {
q"""..${modsForGeneratedCompanion(mods)} object ${Term.Name(tname.value)} {
$algebraAlias
$singletonAlias
$applyMethod
Expand Down Expand Up @@ -65,7 +65,8 @@ object DieselImpl {
}
}

private def objectModsOnly(ms: Seq[Mod]): Seq[Mod] = ms.filter {
private def modsForGeneratedCompanion(ms: Seq[Mod]): Seq[Mod] = ms.filter {
case _: Mod.Annot => false
case mod"final" => false
case mod"abstract" => false
case mod"sealed" => false
Expand Down
4 changes: 2 additions & 2 deletions core/src/test/scala/diesel/KtransAnnotationCompile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import cats.kernel.Monoid

object KtransAnnotationCompileTests {

@ktrans
@ktrans @diesel
trait Trait1[F[_]] {
val vlaThing, vlaThing2: F[Int]
def noArg: F[Int]
Expand All @@ -19,7 +19,7 @@ object KtransAnnotationCompileTests {
private[diesel] def packPriv(p: Byte): F[Byte]
}

@ktrans
@diesel @ktrans
trait TraitWithComp[F[_]] {
def noArg: F[Int]
def ser[A: Monoid](k: String, o: A): F[Unit]
Expand Down
44 changes: 44 additions & 0 deletions examples/src/main/scala/readme/DieselDemo.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package readme

import diesel._, cats._, cats.implicits._

object DieselDemo {

// Declare your DSL
@diesel
trait Maths[F[_]] {
def times(l: Int, r: Int): F[Int]
def add(l: Int, r: Int): F[Int]
}

@diesel
trait Logger[F[_]] {
def info(s: String): F[Unit]
}

// Import companion-to-interpreter aliasing sugar
import Maths.ops._, Logger.ops._
def prog[F[_]: Monad: Maths: Logger](x: Int, y: Int): F[Int] = {
for {
p <- Maths.times(x, y)
_ <- Logger.info(s"Product: $p")
s <- Maths.add(x, y)
_ <- Logger.info(s"Sum: $s")
} yield p + s
}

def main(args: Array[String]): Unit = {

// Wire in our interpreters
implicit val mathsInterp = new Maths[Id] {
def times(l: Int, r: Int) = l * r
def add(l: Int, r: Int) = l + r
}
implicit val loggingInterp = new Logger[Id] {
def info(msg: String) = println(msg)
}

val _ = prog[Id](1, 2)
}

}
44 changes: 0 additions & 44 deletions examples/src/test/scala/readme/DieselDemo.scala

This file was deleted.

0 comments on commit e030509

Please sign in to comment.