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

Support for mutual recursion? + motivating example #83

Open
V-Lamp opened this issue Apr 23, 2017 · 2 comments
Open

Support for mutual recursion? + motivating example #83

V-Lamp opened this issue Apr 23, 2017 · 2 comments

Comments

@V-Lamp
Copy link

V-Lamp commented Apr 23, 2017

Hi, I saw the talk from Greg Pfeil and found the park on mutual recursion really appealing.

I created a simple example of numeric and boolean operations that I would be happy to add to a documentation once I figure how to do traversals. It is a nice domain to document due to some obvious rewrites on boolean expressions.

I appreciate that we need a natural transformation to transform A (is higher-kinded Functor a thing?). But not sure if there is further infrastructure around this.

sealed trait BoolAndCalcF[A[_],I]
// Using AtLeastTwoList as a more complex use case
case class And[A[_]](expressions: AtLeastTwoList[A[Boolean]]) extends BoolAndCalcF[A, Boolean]
case class Or[A[_]](expressions: AtLeastTwoList[A[Boolean]]) extends BoolAndCalcF[A, Boolean]
case class Not[A[_]](wrapped: A[Boolean]) extends BoolAndCalcF[A, Boolean]
case class BoolVal[A[_]](value: Boolean) extends BoolAndCalcF[A, Boolean]

// A bridge from calculation to booleans
case class Compare[A[_],I : Numeric, J: Numeric](left: A[I], op: CompOp, right: A[I]) extends BoolAndCalcF[A, Boolean]

case class Add[A[_], I : Numeric](left: A[I], right: A[I]) extends BoolAndCalcF[A, I]
//To show it would not compose with the rest due to Option
case class Divide[A[_], I : Numeric](left: A[I], right: A[I]) extends BoolAndCalcF[A, Option[I]]
case class Num[A[_], I : Numeric](value: I) extends BoolAndCalcF[A, I]

sealed trait CompOp
object CompOp {
  case object GT extends CompOp
  case object LT extends CompOp
  case object EQ extends CompOp
  case object NE extends CompOp
  case object GE extends CompOp
  case object LE extends CompOp
}
//import cats.data.OneAnd
//type AtLeastTwoList[A] = OneAnd[OneAnd[List,A],A]
case class AtLeastTwoList[A](head: A, second:A, tail: List[A]) {
  def map[B](f: A => B) = AtLeastTwoList(f(head), f(second), tail.map(f))
  def fold[B](h: A => B)(f: (B, A) => B): B = tail.foldLeft[B](f(h(head), second))(f)
}
@sellout
Copy link
Contributor

sellout commented Apr 23, 2017

Cool!

So, there’s a PR (#28) with a bunch of mutual-recursion stuff on it, including working examples. However, a regression in scalac means it doesn’t compile anymore. I have an in-progress PR against scalac, but haven’t had a chance to finish it up.

@V-Lamp
Copy link
Author

V-Lamp commented Apr 23, 2017

Hi Greg, thanks for the update, looks promising!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants