2011-04-23 46 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