And
Regarding taking the coproduct of two algebras, is it the scalaz.Coproduct that you are referring to?I was looking into this, but I am running into a variance issue using that with Free.--
I have a complete example below, but it seems that the issue is caused since I define the coproduct of the algebras astype FooBarLang[A] = Coproduct[FooLanguage, BarLanguage, A]instead oftype FooBarLang[+A] = Coproduct[FooLanguage, BarLanguage, A]Would it be feasible define Coproduct as `sealed trait Coproduct[F[+_], G[+_], +A]`? However, perhaps there is a better way to go about this.Thanks,-EricPS - Exampleimport scalaz.{-\/, \/-, \/, ~>, Cofree, Free, Functor, Zap}import Free.{Gosub, Return, Suspend}object tester {type Foo = Stringtype Bar = Stringsealed trait FooLanguage[+A]case class GetFoo[+A](id: String, h: Foo => A) extends FooLanguage[A]sealed trait BarLanguage[+A]case class GetBar[+A](id: String, h: Bar => A) extends BarLanguage[A]implicit val fooLanguageFunctor: Functor[FooLanguage] =new Functor[FooLanguage] {def map[A, B](a: FooLanguage[A])(f: A => B): FooLanguage[B] = a match {case GetFoo(i, h) => GetFoo(i, x => f(h(x)))}}implicit val barLanguageFunctor: Functor[BarLanguage] =new Functor[BarLanguage] {def map[A, B](a: BarLanguage[A])(f: A => B): BarLanguage[B] = a match {case GetBar(i, h) => GetBar(i, x => f(h(x)))}}def getFoo(id: String): Free[FooLanguage, Foo] =Suspend[FooLanguage, Foo](GetFoo(id, Return[FooLanguage, Foo](_)))def getBar(id: String): Free[BarLanguage, Bar] =Suspend[BarLanguage, Bar](GetBar(id, Return[BarLanguage, Foo](_)))// Cause of the issue using A and not +Atype FooBarLang[A] = Coproduct[FooLanguage, BarLanguage, A]def foo = new (FooLanguage ~> FooBarLang) {def apply[A](foo: FooLanguage[A]) = Coproduct.leftc(foo)}def bar = new (BarLanguage ~> FooBarLang) {def apply[A](bar: BarLanguage[A]) = Coproduct.rightc(bar)}//[error]inferred kinds of the type arguments (tester.FooBarLang) do//not conform to the expected kinds of the type parameters (type T).//[error] tester.FooBarLang's type parameters do not match type T's//expected parameters: [error] type A is invariant, but type _ is//declared covariant//[error] val test = getFoo("a").mapSuspension(foo)//[error] ^val test = getFoo("a").mapSuspension(foo)}
On Monday, May 13, 2013 8:23:46 PM UTC-4, Runar Bjarnason wrote:I am taking an approach like that in building an API for accessing CouchDB. So far it's working really well. For example, we can have different algebras for reading and writing a database, and use the coproduct of the two for read/write access. Also, I have different languages for "things that operate on databases at the global couch level", and "things that operate on individual databases".Sorry I don't have an answer for your first (free/cofree) question. I haven't had the time recently to look into it.RunarOn Mon, May 13, 2013 at 7:27 PM, eric thul <eric...@gmail.com> wrote:hi All,To steer the topic of this thread in somewhat of a different direction, I have been considering integrating Free monads and little languages into an application, and I am curious about anyone's experience going this route. Let's say that there would be at least a few languages in the application that one might want to compose to produce larger Free monad language-based APIs.For those who have done this before, what are your thoughts on this approach? How did it work out at the end of the day? Were there any gotchas that came up along the way?I would very much appreciate any thoughts or feedback on the subject.Best,-Eric--
On Saturday, May 4, 2013 8:05:57 PM UTC-4, eric thul wrote:hi All,I have example (below) of a Free language along with its dual. I was looking into using the zapWith functionality on the Free type to produce a result. However, I am a bit stumped as to why the call to zapWith (below) yields a stack overflow instead of the desired result. There must be something I a missing here, any pointers would be most appreciated.Also, I am curious whether the usage of Cofree in the example below is on the mark or not. What I mean is that I would like to perhaps yield an optional value when I access the id from the DB type. For example, I am not sure I understand how this might work if I wanted to call `db.get(id)` as opposed to just `db(id)`.Thanks,-EricPS - This is using scalaz 7.0.0 on scala 2.10.0import scalaz.{-\/, \/-, \/, Cofree, Free, Functor, Zap}import Free.{Gosub, Return, Suspend}object tester {type Foo = Stringsealed trait FooLanguage[+A]case class GetFoo[+A](id: String, h: Foo => A) extends FooLanguage[A]sealed trait FooLanguageDual[+A]case class GetFooDual[+A](a: A, k: String => Foo) extends FooLanguageDual[A]implicit val fooLanguageFunctor: Functor[FooLanguage] =new Functor[FooLanguage] {def map[A, B](a: FooLanguage[A])(f: A => B): FooLanguage[B] = a match {case GetFoo(i, h) => GetFoo(i, x => f(h(x)))}}implicit val fooLanguageDualFunctor: Functor[FooLanguageDual] =new Functor[FooLanguageDual] {def map[A, B](a: FooLanguageDual[A])(f: A => B): FooLanguageDual[B] = a match {case GetFooDual(a, k) => GetFooDual(f(a), k)}}implicit val fooLanguageDualZap: Zap[FooLanguage, FooLanguageDual] =new Zap[FooLanguage, FooLanguageDual] {def zapWith[A, B, C](fa: FooLanguage[A], gb: FooLanguageDual[B])(f: (A, B) => C) = (fa, gb) match {case (GetFoo(i, h), GetFooDual(b, k)) => f(h(k(i)), b)}}def getFoo(id: String): Free[FooLanguage, Foo] =Suspend[FooLanguage, Foo](GetFoo(id, Return[FooLanguage, Foo](_)))type DB = Map[String, Foo]
val db: DB = Map("test" -> "foo")def run(db: DB): Cofree[FooLanguageDual, DB] =Cofree.unfoldC[FooLanguageDual, DB](db) { db =>GetFooDual(db, db(_))}val program =for {x <- getFoo("test")} yield s"howdy $x"// Stackoverflowslazy val res: String = program.zapWith(run(db))((a, _) => a)def run2[A](p: Free[FooLanguage, A], db: DB): A =p.resume.fold({case GetFoo(i, h) => run2(h(db(i)), db)}, a => a)// Produces "howdy foo"lazy val res2: String = run2(program, db)}
You received this message because you are subscribed to the Google Groups "scalaz" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scalaz+un...@googlegroups.com.
To post to this group, send email to sca...@googlegroups.com.
Visit this group at http://groups.google.com/group/scalaz?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
You received this message because you are subscribed to the Google Groups "scalaz" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scalaz+un...@googlegroups.com.
To post to this group, send email to sca...@googlegroups.com.
Visit this group at http://groups.google.com/group/scalaz?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.