I am building a aggregation framework with some code which looks like this
trait Aggregate[T <: Aggregate[T, K], K] { self: T =>
def plus(another: T): T
def show: K
}
I have couple of aggregations like this,
case class Count(value: Long = 1) extends Aggregate[Count, Long] {
def plus(another: Count) = Count(value + another.value)
def show = value
}
Once i define a aggregation which is like this,
case class By[T <: Aggregate[T, K], K, G](values: HashMap[G, T]) extends Aggregate[By[T, K, G], Map[G, K]] {
override def plus(another: By[T, K, G]): By[T, K, G] = By(values.merged(another.values){case ((k1,v1), (k2,v2)) => (k1, v1 plus v2)})
override def show: Map[G, K] = values.map{case (k,v) => k -> v.show}
}
object By {
def apply[T <: Aggregate[T,K], K, G](key:G, value:T):By[T, K, G] = By(HashMap(key -> value))
}
I cannot write something like this
By("key1", Count(100))
Instead i had to write this
By[Count, Long, String]("key1", Count(100))
Since its not figuring out the Long
part, I hate to specify those types, is there a cleaner way to achieve that?
The Scala compiler can often infer the type of an expression so you don't have to declare it explicitly.
Scala compiler can automatically infer types of each variable declared. If the value of a variable is declared in double-quotes it will automatically be inferred as String. Also, the compiler can infer any value in a single quote is inferred as Char.
=> is syntactic sugar for creating instances of functions. Recall that every function in scala is an instance of a class. For example, the type Int => String , is equivalent to the type Function1[Int,String] i.e. a function that takes an argument of type Int and returns a String .
Trick I learned:
object By {
def apply[T <: Aggregate[T,K], K, G](key:G, value:T with Aggregate[T,K]):By[T, K, G] = By(HashMap(key -> value))
}
The with Aggregate[T,K]
refinement somehow helps the compiler figure out the types.
I suggest using Monoid
and Show
type classes. You may even want to use kittens (sorry, don't have enough rep to add another link; just Google "scala kittens derivation") to automatically derive the Monoid
and Show
instances for your case classes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With