Alternative effects
neotypes comes with four effect implementations: Future, cats-effect, Monix & ZIO.
scala.concurrent.Future (neotypes)
import neotypes.GraphDatabase
import neotypes.mappers.ResultMapper // Allows to decode query results. // Allows to decode query results.
import neotypes.syntax.all._ // Provides the query extension method. // Provides the query extension method.
import scala.concurrent.{Await, Future}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._ // Provides the second extension method. // Provides the second extension method.
import org.neo4j.driver.AuthTokens
val driver = GraphDatabase.asyncDriver[Future]("bolt://localhost:7687", AuthTokens.basic("neo4j", "****"))
val program: Future[String] = for {
data <- "MATCH (p: Person { name: 'Charlize Theron' }) RETURN p.name"
.query(ResultMapper.string)
.single(driver)
_ <- driver.close
} yield data
val data: String = Await.result(program, 1.second)
Note: The previous example does not handle failures. Thus, it may leak resources.
cats.effect.IO (neotypes-cats-effect)
import cats.effect.{IO, Resource}
import cats.effect.unsafe.implicits.global
import neotypes.{AsyncDriver, GraphDatabase}
import neotypes.cats.effect.implicits._ // Brings the implicit neotypes.Async[IO] instance into the scope. // Brings the implicit neotypes.Async[IO] instance into the scope.
import neotypes.mappers.ResultMapper // Allows to decode query results. // Allows to decode query results.
import neotypes.syntax.all._ // Provides the query extension method. // Provides the query extension method.
import org.neo4j.driver.AuthTokens
val driver: Resource[IO, AsyncDriver[IO]] =
GraphDatabase.asyncDriver[IO]("bolt://localhost:7687", AuthTokens.basic("neo4j", "****"))
val program: IO[String] = driver.use { d =>
"MATCH (p: Person { name: 'Charlize Theron' }) RETURN p.name"
.query(ResultMapper.string)
.single(d)
}
val data: String = program.unsafeRunSync()
cats.effect.neotypes.Async[F] (neotypes-cats-effect)
import cats.effect.{Async, IO, Resource}
import cats.effect.unsafe.implicits.global
import neotypes.{AsyncDriver, GraphDatabase}
import neotypes.cats.effect.implicits._ // Brings the implicit neotypes.Async[IO] instance into the scope. // Brings the implicit neotypes.Async[IO] instance into the scope.
import neotypes.mappers.ResultMapper // Allows to decode query results. // Allows to decode query results.
import neotypes.syntax.all._ // Provides the query extension method. // Provides the query extension method.
import org.neo4j.driver.AuthTokens
def driver[F[_] : Async]: Resource[F, AsyncDriver[F]] =
GraphDatabase.asyncDriver[F]("bolt://localhost:7687", AuthTokens.basic("neo4j", "****"))
def program[F[_] : Async]: F[String] = driver[F].use { d =>
"MATCH (p: Person { name: 'Charlize Theron' }) RETURN p.name"
.query(ResultMapper.string)
.single(d)
}
val data: String = program[IO].unsafeRunSync()
monix.eval.Task (neotypes-monix)
import cats.effect.Resource
import monix.eval.Task
import monix.execution.Scheduler.Implicits.global
import neotypes.{AsyncDriver, GraphDatabase}
import neotypes.mappers.ResultMapper // Allows to decode query results.
import neotypes.monix.implicits._ // Brings the implicit neotypes.Async[Task] instance into the scope.
import neotypes.syntax.all._ // Provides the query extension method.
import scala.concurrent.duration._ // Provides the second extension method.
import org.neo4j.driver.AuthTokens
val driver: Resource[Task, AsyncDriver[Task]] =
GraphDatabase.asyncDriver[Task]("bolt://localhost:7687", AuthTokens.basic("neo4j", "****"))
val program: Task[String] = driver.use { d =>
"MATCH (p: Person { name: 'Charlize Theron' }) RETURN p.name"
.query(ResultMapper.string)
.single(d)
}
val data: String = program.runSyncUnsafe(1.second)
zio.Task (neotypes-zio)
import neotypes.{AsyncDriver, GraphDatabase}
import neotypes.mappers.ResultMapper // Allows to decode query results. // Allows to decode query results.
import neotypes.syntax.all._ // Provides the query extension method. // Provides the query extension method.
import neotypes.zio.implicits._ // Brings the implicit neotypes.Async[Task] instance into the scope. // Brings the implicit neotypes.Async[Task] instance into the scope.
import org.neo4j.driver.AuthTokens
import zio.{Runtime, Scope, Task, Unsafe, ZIO}
val driver: ZIO[Scope, Throwable, AsyncDriver[Task]] =
GraphDatabase.asyncDriver[Task]("bolt://localhost:7687", AuthTokens.basic("neo4j", "****"))
val program: Task[String] = ZIO.scoped {
driver.flatMap {d =>
"MATCH (p: Person { name: 'Charlize Theron' }) RETURN p.name"
.query(ResultMapper.string)
.single(d)
}
}
val data: String = Unsafe.unsafe { implicit unsafe =>
Runtime.default.unsafe.run(program).getOrThrow()
}
Custom effect type
In order to support your any other effect type,
you need to implement the neotypes.Async.Aux[F[_], R[_]]
typeclasses
and add them to the implicit scope.
The type parameters in the signature indicate:
F[_]
- the effect type.R[_]
- the resource used to wrap the creation of Drivers.