2015-03-13 37 views
2

Scala類型推理非常好,很容易使用,而不必寫兩次東西。當你需要的時候,傷害越多。一個這樣的例子是函數類型。可以通過推理來定義函數類型嗎?

有時我想爲某些函數簽名創建一個命名類型。以某種方式可能嗎?有什麼方法可以獲得函數的編譯時類型,以便在定義FType時不必再次鍵入它?

object Foo { 
    def f(a:Int, b:Int, x:Double, y:Double, name:String) : Unit = {} 

    //type FType = typeOf(f) // can compiler provide me a compile time type somehow? 
    type FType = (Int,Int,Double,Double,String) => Unit 

    def callF(func:FType) = func(0,0,0,0,"") 
} 

有沒有像Scala中的C++ decltype可以用於此目的?

回答

2

我不太清楚你想在這裏實現什麼,如果我理解正確,你想避免兩次輸入(a:Int, b:Int, x:Double, y:Double, name:String)

那麼你自己先定義FType,然後在fcallF中簡單地重用它呢?

object Foo { 
    type FType = (Int,Int,Double,Double,String) => Unit 

    def f: FType = (a, b, x, y, name) =>() 

    def callF(func: FType) = func(0,0,0,0,"") 
} 

如果你真的想在抽象FType,這是一個顯著不同的問題,但它似乎並不像你通過調用func(0,0,0,0,"")迫使類型的情況。

您在Scala中沒有decltype,因爲類型不是一流的公民,例如他們可以在Idris中。也就是說,你應該可以使用Shapeless和/或宏編寫它。

如果您想修復類型和參數並重用它們,最簡單的解決方案是將它們變成case class。然後,您可以使用import直接訪問你的域:

object Foo { 
    case class FArgs(a: Int, b: Int, x: Double, y: Double, name: String) 

    def f(args: FArgs): Unit = { 
    import args._ 
    println(name) // or whatever you want to do 
    } 

    def callF(func: FArgs => Unit) = func(FArgs(0,0,0,0,"")) 
} 
+2

這無疑是進步,但仍然有我寫這個'(A,B,X,Y,名)'這是一種重複自己的。從'f'推出'FType'可以避免這種情況,但我想這是不可能的。 – Suma 2015-03-13 15:37:02

+0

..不,我不想抽象'FType',我只是想避免在定義'f'和用於它的回調類型時重複自己。 – Suma 2015-03-13 15:46:35

+1

如果你想定義多個類型爲「FType」的函數,並且你希望它們不僅是相同的類型,而且要有相同的參數名稱,這是我能想到的唯一重複,那麼你應該簡單地定義一個案例類。像case class FArgs(a:Int,b:Int,x:Double,y:Double,name:String)' – blouerat 2015-03-13 15:56:31

相關問題