Created
July 9, 2014 03:50
-
-
Save chrislewis/71f0a384ed5426646720 to your computer and use it in GitHub Desktop.
This file contains 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
/* | |
CanBuildFrom is easily abused such that the ubiquitous higher order function | |
map can be repurposed as fold. This is not good; this example demonstrates | |
a design flaw, not a strength. | |
*/ | |
import scala.language.postfixOps | |
import scala.collection.generic.CanBuildFrom | |
import scala.collection.mutable.Builder | |
import scala.math.Numeric | |
object MapIsFold { | |
/** Given a higher kind K, a zero value of type B, and a function combining an | |
A and B into a B, yield a CanBuildFrom that produces a Builder which will | |
accumulate A values into a single B value. */ | |
def cbf[K[_], A, B](zero: B, f: (A, B) => B) = | |
new CanBuildFrom[K[A], A, B] { | |
override def apply() = new Builder[A, B] { | |
private var i = zero | |
def +=(elem: A) = { | |
i = f(elem, i) | |
this | |
} | |
def clear() { i = zero } | |
def result() = i | |
} | |
override def apply(from: K[A]): Builder[A, B] = apply() | |
} | |
/** A function to lift implicitly available Numeric instances into | |
CanBuildFrom instances that support folding. */ | |
implicit def catamorphicCbf[K[_], A](implicit n: Numeric[A]) = | |
cbf[K, A, A](n.zero, n.plus) | |
} | |
/* | |
scala> import MapIsFold._ | |
import MapIsFold._ | |
scala> List(1,2,3).map(1+) | |
res0: Int = 9 | |
scala> Set(1,2,3).map(1+) | |
res1: Int = 9 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment