Skip to content

Instantly share code, notes, and snippets.

@dacr
Created July 22, 2013 21:35
Show Gist options
  • Save dacr/6057924 to your computer and use it in GitHub Desktop.
Save dacr/6057924 to your computer and use it in GitHub Desktop.
Playing with generic numbers and collections
// -----------------------------------------------
// Generic square method that works with any kind
// of numerical type
// -----------------------------------------------
def square[N](x: N)(implicit n: Numeric[N]) = {
n.times(x, x)
}
square(10d)
square(BigDecimal(4))
square(2)
// -----------------------------------------------
// apply square on a collection
// -----------------------------------------------
def squares[N](x: Iterable[N])(implicit n: Numeric[N]) = x.map(v => n.times(v, v))
squares(1 :: 2 :: Nil)
squares(1d :: 2d :: Nil)
squares(BigDecimal(1) :: BigDecimal(2) :: Nil)
// -----------------------------------------------
// Now let's define a generic squares method
// that can deal with any kind of numerical types and
// returns exactly the collection type it takes in input
// -----------------------------------------------
import scala.collection.generic.CanBuildFrom
def gsquares[N, I[N] <: Iterable[N]](values: I[N])(implicit bf: CanBuildFrom[I[N], N, I[N]], n: Numeric[N]): I[N] = {
var builder = bf.apply()
for (value <- values) { builder += n.times(value, value) }
builder.result
}
gsquares(Seq(1,2,3))
gsquares(List(1,2,3))
gsquares(Vector(BigDecimal(1),BigDecimal(2),BigDecimal(3)))
// But it still doesn't work with Arrays
//gsquares(Array(1,2,3))
// -----------------------------------------------
// Now the same revisited that works now with
// any kind of collections and numerical types
// -----------------------------------------------
import scala.collection.generic.CanBuildFrom
def asquares[N, C](values: C)
(implicit c2i: C => Iterable[N], bf: CanBuildFrom[C, N, C], n: Numeric[N]): C = {
var builder = bf.apply()
for (value <- values) { builder += n.times(value, value) }
builder.result
}
asquares(Seq(1,2,3))
asquares(List(1,2,3))
asquares(Vector(BigDecimal(1),BigDecimal(2),BigDecimal(3)))
asquares(Array(1,2,3))
asquares(Set(2,4))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment