Skip to content

Instantly share code, notes, and snippets.

@debasishg
Last active June 20, 2016 04:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save debasishg/647723d3db3e408acfbd3be75795036e to your computer and use it in GitHub Desktop.
Save debasishg/647723d3db3e408acfbd3be75795036e to your computer and use it in GitHub Desktop.
import scalaz.Free
sealed trait Account
sealed trait RepoF[A]
// he algebraic data types
case class Query(no: String) extends RepoF[Account]
case class Store(account: Account) extends RepoF[Unit]
case class Delete(no: String) extends RepoF[Unit]
// the free monad
type Repo[A] = Free[RepoF, A]
trait Repository {
def store(account: Account): Repo[Unit] =
Free.liftF(Store(account))
def query(no: String): Repo[Account] =
Free.liftF(Query(no))
def delete(no: String): Repo[Unit] =
Free.liftF(Delete(no))
/**
* I create this DSL out of the above functions. I am still within
* the module `Repository` and can do this because `Repo` is a monad. How can I
* do this same thing with freek ? Note I am still within the module `Repo` and
* have not yet defined my final co-product like `PRG` or `O` as in the examples of `freek`.
* With freek, we deal with pure ADTs within the module which is not a monad - hence I
* need to wait till the final composition of the DSL (which will involve other moduels as well)
* to create such functions.
*
* Is there any way in freek to have free monads like the above in the individual modules and
* then use the `onionT` trick just for the monad transformation (using hk co-products) and
* interpreter composition ?
**/
def update(no: String, f: Account => Account): Repo[Unit] = for {
a <- query(no)
_ <- store(f(a))
} yield ()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment