Scala隐含功能对象之间的转换?

时间:2011-04-23 03:53:59

标签: java scala

我正在尝试重新绑定scala.math中的一些函数来获取和返回Float个对象而不是Double个对象,这样我就可以将它们绑定到一个有效的函数注册器具有获取和返回Float个对象的函数。我试过这个规则:

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

它不起作用。编译器抱怨我的函数是(Double)=>Float而不是(Float)=>Float。有人能指出我正确的方向吗?

编辑:我使用此代码的代码如下:

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获取函数名称的String和函数对象以将其关联。

3 个答案:

答案 0 :(得分:0)

此处不需要结构类型或类型参数,

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

然后在使用中,

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

答案 1 :(得分:0)

我不知道究竟发生了什么,但它首先检查函数的返回类型,如果无法解决,则会失败。但是如果你使其能够修复返回类型,那么它会继续检查整个函数。

所以你可以通过创建两个含义来实现:

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

答案 2 :(得分:0)

我认为潜在的问题(在我们删除已经存在于pref中的implicits,不必要的结构类型,然后将自己局限于未过载的数学函数之后)是弱一致性和eta扩展之间的一种奇怪的类型推断交互。参数类型Float符合预期的参数类型Double,因此函数类型的隐式转换不会触发;它为结果类型提供了支持,这为时已晚。它已经确定参数类型是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>