Created
March 14, 2015 01:49
-
-
Save xuwei-k/9d815c756744e8b43fb7 to your computer and use it in GitHub Desktop.
deriving Foldable in Scala
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
libraryDependencies += "com.chuusai" %% "shapeless" % "2.2.0-RC1" | |
scalaVersion := "2.11.6" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
info] Running DerivingFoldableExample | |
[error] (run-main-15) java.lang.StackOverflowError | |
java.lang.StackOverflowError | |
at scala.runtime.BoxesRunTime.boxToInteger(BoxesRunTime.java:69) | |
at DerivingFoldableExample$$anonfun$main$1.apply(Foldable.scala:59) | |
at Foldable$$anon$1.foldLeft(Foldable.scala:13) | |
at Foldable$$anon$2.foldLeft(Foldable.scala:20) | |
at Foldable$$anon$4.foldLeft(Foldable.scala:38) | |
at Foldable$$anon$3.foldLeft(Foldable.scala:29) | |
at Foldable$$anon$4.foldLeft(Foldable.scala:38) | |
at Foldable$$anon$2.foldLeft(Foldable.scala:20) | |
at Foldable$$anon$2.foldLeft(Foldable.scala:20) | |
at Foldable$$anon$4.foldLeft(Foldable.scala:38) | |
at Foldable$$anon$3.foldLeft(Foldable.scala:29) | |
at Foldable$$anon$4.foldLeft(Foldable.scala:38) | |
at Foldable$$anon$2.foldLeft(Foldable.scala:20) | |
at Foldable$$anon$2.foldLeft(Foldable.scala:20) | |
at Foldable$$anon$4.foldLeft(Foldable.scala:38) | |
at Foldable$$anon$3.foldLeft(Foldable.scala:29) | |
at Foldable$$anon$4.foldLeft(Foldable.scala:38) | |
at Foldable$$anon$2.foldLeft(Foldable.scala:20) | |
at Foldable$$anon$2.foldLeft(Foldable.scala:20) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import shapeless._ | |
trait Foldable[F[_]] { | |
def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B): B | |
} | |
object Foldable extends Foldable0 { | |
def apply[F[_]](implicit F: Lazy[Foldable[F]]): Foldable[F] = F.value | |
implicit val idFoldable: Foldable[Id] = | |
new Foldable[Id] { | |
def foldLeft[A, B](fa: A, b: B)(f: (B, A) => B) = | |
f(b, fa) | |
} | |
implicit def hcons[F[_]](implicit F: IsHCons1[F, Foldable, Foldable]): Foldable[F] = | |
new Foldable[F] { | |
override def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B) = { | |
val (hd, tl) = F.unpack(fa) | |
F.ft.foldLeft(tl, F.fh.foldLeft(hd, b)(f))(f) | |
} | |
} | |
implicit def ccons[F[_]](implicit F: IsCCons1[F, Foldable, Foldable]): Foldable[F] = | |
new Foldable[F] { | |
def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B) = | |
F.unpack(fa) match { | |
case Left(l) => | |
F.fh.foldLeft(l, b)(f) | |
case Right(r) => | |
F.ft.foldLeft(r, b)(f) | |
} | |
} | |
implicit def generic[F[_]](implicit F: Generic1[F, Foldable]): Foldable[F] = | |
new Foldable[F] { | |
def foldLeft[A, B](fa: F[A], b: B)(f: (B, A) => B) = | |
F.fr.foldLeft(F.to(fa), b)(f) | |
} | |
} | |
sealed abstract class Foldable0 { | |
implicit def constFoldable[T]: Foldable[Const[T]#λ] = | |
new Foldable[Const[T]#λ] { | |
override def foldLeft[A, B](fa: T, b: B)(f: (B, A) => B) = | |
b | |
} | |
} | |
sealed abstract class IList[A] | |
final case class ICons[A](head: A, tail: IList[A]) extends IList[A] | |
final case class INil[A]() extends IList[A] | |
object DerivingFoldableExample { | |
def main(args: Array[String]): Unit = { | |
val list = (1 to 100000).foldLeft(ICons(0, INil())){ (acc, i) => ICons(i, acc) } | |
println(Foldable[IList].foldLeft(list, 0)(_ + _)) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment