2011-07-08 68 views
4

我想知道如何在Scala中調用類型參數化方法時可能具有默認類型。假設我有以下方法某處:方法調用的默認類型

def apply[A](id: String)(implicit processor: Processor[A]) = 
    processor(data get id) 

我想AString,當編譯器沒有關於來推斷哪種類型的提示。所以,我可以重載我的定義是:

def apply(id: String)(implicit processor: Processor[String]) = 
    processor(data get id) 

但刪除後兩種方法都會有相同的簽名......有沒有什麼辦法,以提供一個默認的類型?

回答

7

你可以通過定義下面的幻像t YPE:

sealed class DefaultsTo[A, B] 
trait LowPriorityDefaultsTo { 
    implicit def overrideDefault[A,B] = new DefaultsTo[A,B] 
} 
object DefaultsTo extends LowPriorityDefaultsTo { 
    implicit def default[B] = new DefaultsTo[B, B] 
} 

那麼你的方法可以寫成

def apply[A](id: String)(implicit e: A DefaultsTo String, 
            processor: Processor[A]) = 
    processor(data get id) 

overrideDefault保證,對於任何兩個指定的類型,AB,編譯器可以始終提供DefaultsTo[A, B]類型的對象的定義(例如DefaultsTo[Int, String])。然而,如果兩種類型之一未指定(例如DefaultsTo[A, String]),編譯器將優選識別這兩種類型(在該示例中提供DefaultsTo[String, String],並因此推斷出String爲未指定類型A)。

作爲Naftoli Gugenheim pointed out in this mailing list thread,還可以實現用一些漂亮的語法與語境範圍:

class Has[B] { 
    type AsDefault[A] = A DefaultsTo B 
} 

def apply[A : Has[String]#AsDefault : Processor](id: String) = 
    implicitly[Processor[A]].apply(data get id) 
+1

請參閱[此問題](http://stackoverflow.com/questions/4403906/is-it-possible-in-scala-to-force-the-caller-to-specify-a-type-parameter-for-a相關技術。 –

0

在這種情況下,你可以使用一個小竅門

class C { 
    def apply[A](id: String) = (processor: Processor[A]) => id + processor 
    def apply(id: String)(implicit processor: Processor[String]) = id + processor 
} 

在更普遍的情況下,不知道SRY ...

編輯

我忘了你所需要的processor到是implicit所以它不會編譯...

+0

如果他想編譯器隱含提供處理器不工作。 –

+0

Yeap,只是注意到我自己,無論如何thx。 – agilesteel