2011-04-23 83 views
4

我试图重新绑定一些功能scala.math采取并返回Float对象,而不是Double对象,以便我可以将它们绑定到一个函数注册商是与接受和返回Float对象功能的工作原理。我试过这个规则:Scala函数对象之间的隐式转换?

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为函数的名称和功能对象将其与关联。

+2

请显示您是如何使用代码的。 – 2011-04-23 04:54:53

+0

@Daniel C. Sobral:完成。 – 2011-04-23 20:07:40

+0

“Functions.register”的类型签名是什么?我认为这个错误发生在对它的调用上,对吧? – 2011-04-23 23:41:30

回答

0

我不知道究竟是怎么回事,但对于它首先检查函数的返回类型,如果无法解决则返回失败。但如果你使它有可能修复返回类型,那么它继续检查整个函数。

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

出于好奇,使用'Double'而不是'Float'会更好吗?该应用程序是一个图形计算器,这个系统允许插入额外的功能。 – 2011-04-24 21:12:16

+1

@Nathan肯定。 “Float”是在Java-land中被遗忘的一类。 – 2011-04-25 13:10:37

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 
+0

误导。它实际上并不工作 - 用'log'来尝试,它不会超载。它似乎在这里工作,因为'abs'有一个'(Float)Float'版本。 – 2011-04-24 05:21:04

0

我认为,根本的问题(在我们删除implicits这已经在PREDEF,不必要的结构类型,然后把自己限制其AREN数学函数:

所以,你可以通过创建两个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> 
+0

你有什么想法,为什么我的两个implicits使它的工作?没有一个是足够的。 – 2011-04-25 13:27:19