One of the challenges with implicits is that they must be declared in a type. You cannot declare a "global implicit" conversion to be used across all code compiled with it. Therefore, it would seem that you must redeclare implicits in every class that you want to use them in.
Actually, you don't. You can place them in a common trait, the Scala equivalent of Java's interface. A trait implements mixins, which (in Java terms) are like not-completely-abstract classes. This enables pseudo-multiple inheritance to be used in Scala! Example (taken from exprtreelib code):
// ExpressionNodeTypes.scala; org.nathanmoos.magnificalc.exprtreelib
trait Implicits
{
implicit def closure2Function[T <: { def apply(x:Double):Double }](closure:T) = new Function() {
override def evaluate(x:Double):Double = closure.apply(x)
}
}
...
object Functions
{
...
def register(name:String, func:Function) = ...
...
}
// InternalFunctions.scala; org.nathanmoos.magnificalc.exprtreelib.functions
object InternalFunctions extends Implicits
{
...
def registerAll() = {
Functions.register("ln", log _)
Functions.register("log", log10 _)
Functions.register("sqrt", sqrt _)
Functions.register("sin", sin _)
Functions.register("cos", cos _)
Functions.register("tan", tan _)
Functions.register("csc", csc _)
Functions.register("sec", sec _)
Functions.register("cot", cot _)
Functions.register("sinh", sinh _)
Functions.register("cosh", cosh _)
Functions.register("tanh", tanh _)
Functions.register("acos", acos _)
Functions.register("asin", asin _)
Functions.register("atan", atan _)
}
}
object MyNewFunctions extends BaseClass with ImplicitsThis example, while quite useless, demonstrates that the new Implicits trait can be used to share implicit type conversions across classes. Look for more in this new series: How-to in Scala!
{
def plusFour(arg:Double):Double = arg + 4
def registerAll() = {
Functions.register("plusFour", plusFour _)
}
}
No comments:
Post a Comment