Skip to content

Instantly share code, notes, and snippets.

@YoEight
Created May 15, 2013 16:42
Show Gist options
  • Save YoEight/5585354 to your computer and use it in GitHub Desktop.
Save YoEight/5585354 to your computer and use it in GitHub Desktop.
cartesian product using anamorphism
object ex {
def ana[A, B](start: B)(f: B => Option[(A, B)]): List[A] = f(start) match {
case Some((a, b)) => a :: ana(b)(f)
case _ => Nil
}
def cartesian[A](xss: List[List[A]]): List[List[(A, A)]] = ana(xss) {
case xs :: vs :: rest =>
val action = for {
x <- xs
v <- vs
} yield (x, v)
Some((action, rest))
case _ => None
}
}
@cchantep
Copy link

object Cartesian {
  def yesfilter[A](a: A, b: A) = true

  def combine[A, B, C](a: Traversable[A], b: Traversable[B], f: (A, B)  Boolean = yesfilter _)(m: (A, B)  C): Seq[C] = {
    @annotation.tailrec
    def combine(c: Traversable[B], e: A, o: Seq[C]): Seq[C] =
      c match {
        case Nil  o
        case h :: t 
          if (f(e, h)) combine(t, e, o :+ m(e, h))
          else combine(t, e, o)
      }

    @annotation.tailrec
    def go(x: Traversable[A], y: Traversable[B], o: Seq[C]): Seq[C] = x match {
      case Nil     o
      case h :: t  go(t, y, combine(y, h, o))
    }

    go(a, b, Nil)
  }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment