Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use of puretest in freestyle #1

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import sbtorgpolicies.runnable.syntax._

resolvers ++= Seq(
"Habla repo - releases" at "http://repo.hablapps.com/releases")

lazy val root = (project in file("."))
.settings(moduleName := "root")
.settings(name := "freestyle")
Expand Down Expand Up @@ -28,8 +31,9 @@ lazy val coreJVM = core.jvm
lazy val coreJS = core.js

lazy val tagless = module("tagless")
.dependsOn(core)
.dependsOn(core,effects)
.jsSettings(sharedJsSettings: _*)
.jvmSettings(libraryDependencies += "org.hablapps" %% "puretest-cats" % "0.3.1")
.crossDepSettings(commonDeps ++ Seq(%%("mainecoon-core")): _*)

lazy val taglessJVM = tagless.jvm
Expand Down Expand Up @@ -87,6 +91,9 @@ lazy val Codegen = sbt.config("codegen").hide
lazy val effects = module("effects")
.dependsOn(core)
.jsSettings(sharedJsSettings: _*)
.jvmSettings(
libraryDependencies += "org.hablapps" %% "puretest-cats" % "0.3.1"
)
.crossDepSettings(
commonDeps ++ Seq(
%("cats-mtl-core")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,4 @@ object utils {
z <- if (j < iterations) SOProgram[F](j) else Monad[F].pure(j)
} yield z

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright 2017 47 Degrees, LLC. <http://www.47deg.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package freestyle.tagless
package puretestImpl

import org.hablapps.puretest._
import cats.~>
import cats.instances.either._

class TaglessTestsEither extends TaglessTests.ScalaTest[TaglessTestsEither.P](
TaglessTestsEither.a1,
TaglessTestsEither.a2,
TaglessTestsEither.a3
)

object TaglessTestsEither{
type P[T]=Either[PuretestError[String],T]

implicit val fk: Option ~> P =
λ[Option ~> P](_.toRight(ApplicationError("error")))

import algebras._
import handlers._

val a1 = TG1[P]
val a2 = TG2[P]
val a3 = TG3[P]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright 2017 47 Degrees, LLC. <http://www.47deg.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package freestyle.tagless
package puretestImpl

import org.hablapps.puretest._
import cats.~>
import cats.instances.either._

import TaglessTestsFreeS._

class TaglessTestsFreeS extends TaglessTests.ScalaTest[P](a1,a2,a3)(implicitly, HE,RE,T)

object TaglessTestsFreeS{

/** TG1, TG2, TG3 */

import freestyle._
import freestyle.implicits._
import algebras._
import modules._

import freestyle.effects.either
val e = either[PuretestError[String]]
import e.implicits._

@module trait App {
val tg1: TG1.StackSafe
val tg2: TG2.StackSafe
val tg3: TG3.StackSafe
val te: e.EitherM
}

type P[T]=FreeS[App.Op,T]

// `val a1 = TG1[P]` fails to compile (diverging implicit expansion)
val a1 = new TG1.Handler[P] {
def x(a: Int) = TG1.StackSafe.to[App.Op].x(a)
def y(a: Int) = TG1.StackSafe.to[App.Op].y(a)
}

val a2 = new TG2.Handler[P] {
def x2(a: Int): FS[Int] = TG2.StackSafe.to[App.Op].x2(a)
def y2(a: Int): FS[Int] = TG2.StackSafe.to[App.Op].y2(a)
}

val a3 = new TG3.Handler[P] {
def x3(a: Int): FS[Int] = TG3.StackSafe.to[App.Op].x3(a)
def y3(a: Int): FS[Int] = TG3.StackSafe.to[App.Op].y3(a)
}

/** Handle Error */

implicit val HE = new HandleError[P,String]{
// No need to handle errors in this particular case
def handleError[T](p: P[T])(f: String => P[T]) = p
}

/** Raise Error */

implicit val RE = new RaiseError[P,PuretestError[String]]{
def raiseError[A](err: PuretestError[String]) =
e.EitherM.to[App.Op].error[A](err)
}

/** Tester */

// Couldn't get TG1.Handler[Either[...]] from TG1[Either[...]]
implicit val a1pte: TG1.Handler[Either[PuretestError[String],?]] =
new TG1.Handler[Either[PuretestError[String],?]] {
def x(a: Int) = Right(a)
def y(a: Int) = Right(a)
}

implicit val a2pte: TG2.Handler[Either[PuretestError[String],?]] =
new TG2.Handler[Either[PuretestError[String],?]] {
def x2(a: Int): FS[Int] = Right(a)
def y2(a: Int): FS[Int] = Right(a)
}

implicit val a3pte: TG3.Handler[Either[PuretestError[String],?]] =
new TG3.Handler[Either[PuretestError[String],?]] {
def x3(a: Int): FS[Int] = Right(a)
def y3(a: Int): FS[Int] = Right(a)
}

implicit val T = new Tester[P,PuretestError[String]]{
def apply[T](p: P[T]): Either[PuretestError[String],T] =
p.interpret[Either[PuretestError[String],?]]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* Copyright 2017 47 Degrees, LLC. <http://www.47deg.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package freestyle.tagless
package puretestImpl

import org.hablapps.puretest._

import cats.Monad
import cats.syntax.flatMap._
import cats.syntax.functor._

import algebras._

trait TaglessTests[F[_]] extends FunSpec[F] {

implicit val HE: HandleError[F,String]
implicit val RE: RaiseError[F, PuretestError[String]]
implicit val M: Monad[F]

implicit val a1: TG1[F]
implicit val a2: TG2[F]
implicit val a3: TG3[F]

Describe("Tagless final algebras"){

It("should combine with other tagless algebras"){
(for {
a <- a1.x(1)
b <- a1.y(1)
c <- a2.x2(1)
d <- a2.y2(1)
e <- a3.y3(1)
} yield a + b + c + d + e) shouldBe 5
}

It("should work with derived handlers"){
(for {
x <- TG1[F].x(1)
y <- TG1[F].y(2)
} yield x + y) shouldBe 3
}
}
}

object TaglessTests{
class ScalaTest[F[_]](
val a1: TG1[F],
val a2: TG2[F],
val a3: TG3[F])(implicit
val M: Monad[F],
val HE: HandleError[F,String],
val RE: RaiseError[F,PuretestError[String]],
val Tester: Tester[F,PuretestError[String]]
) extends scalatestImpl.FunSpec[F,String] with TaglessTests[F]
}