Scala implicit conversions between functional objects?

I'm trying to scala.math some functions from scala.math to receive and return Float objects, not Double objects, so that I can bind them to a function registrar that works with functions that accept and return Float objects. I tried this rule:

 implicit def doubleFunc2floatFunc[T <: { def apply(x:Double):Double }] (func:T) = func(_:Float).floatValue 

and it does not work. The compiler complains that my functions are (Double)=>Float , not (Float)=>Float . Can someone point me in the right direction?

EDIT : The code I use in this is as follows:

 package org.nathanmoos.magnificalc.exprtreelib.functions import org.nathanmoos.magnificalc.exprtreelib.Functions import scala.math._ object InternalFunctions { implicit def float2double(x:Float) = x.doubleValue // need an implicit def doubleFunc2floatFunc implicit def double2float(x:Double) = x.floatValue def csc(x:Float):Float = 1f/sin(x) def sec(x:Float):Float = 1f/cos(x) def cot(x:Float):Float = 1f/tan(x) 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 _) } } 

Functions.register takes a String for the name of the function and the function object to associate it with.

+4
source share
3 answers

I don’t know what exactly is happening, but first checks the type of the returned function, and then fails if it cannot solve it. But if you let me fix the return type, then it checks the whole function.

So, you can do this by creating two implications:

 implicit def doubleToFloat(d: Double): Float = d.toFloat implicit def doubleFunc2floatFunc(df : Double => Float) : Float => Float = (f : Float) => df(f) 
0
source

There is no need for structural types or type parameters,

 scala> implicit def doubleFunc2floatFunc(df : Double => Double) : Float => Float = (f : Float) => df(f).toFloat doubleFunc2floatFunc: (df: (Double) => Double)(Float) => Float 

Then when using

 scala> val f : Float => Float = scala.math.abs f: (Float) => Float = <function1> scala> f(-1.0) <console>:8: error: type mismatch; found : Double(-1.0) required: Float f(-1.0) ^ scala> f(-1.0f) res1: Float = 1.0 
0
source

I think that the main problem (after we remove implicits that are already in the predef, unnecessary structure types, and then are limited to mathematical functions that are not overloaded) is the strange interaction of type inference between weak matching and the eta extension. The Float parameter type corresponds to the expected Double parameter type, and therefore, the implicit conversion for the function type does not start; it starts for the result type, which is too late. He already decided that the type of parameter is Double.

 scala> implicit def dd2ff(x: Double => Double): Float => Float = x => x dd2ff: (x: (Double) => Double)(Float) => Float scala> def dd(x: Double) = x dd: (x: Double)Double scala> val ff: Float => Float = (dd _) <console>:9: error: type mismatch; found : Double required: Float val ff: Float => Float = (dd _) ^ scala> val x = dd _ x: (Double) => Double = <function1> scala> val ff: Float => Float = x ff: (Float) => Float = <function1> 
0
source

All Articles