Тип по умолчанию для вызовов методов - PullRequest
4 голосов
/ 08 июля 2011

Я хотел бы знать, как, если возможно иметь тип по умолчанию при вызове метода с параметризацией типа в Scala.Предположим, у меня где-то есть следующий метод:

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

Я бы хотел, чтобы A было String, когда у компилятора нет подсказок о том, какой тип выводить.Таким образом, я могу перегрузить свое определение:

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

Но после стирания оба метода будут иметь одну и ту же сигнатуру ... Есть ли способ предоставить тип по умолчанию?

Ответы [ 2 ]

7 голосов
/ 08 июля 2011

Этого можно добиться, определив следующий тип фантома:

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 гарантирует, что для любых двух указанных типов, A и B, компилятор всегда может предоставить объект типа DefaultsTo[A, B] (например, DefaultsTo[Int, String]). Однако, если один из двух типов не указан (например, DefaultsTo[A, String]), компилятор предпочтет идентифицировать эти два типа (предоставив, например, DefaultsTo[String, String] и, таким образом, выведя String для неуказанного типа A ).

Как отметил Нафтоли Гугенхайм в этой ветке списка рассылки , вы также можете получить хороший синтаксис для использования с границами контекста:

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)
0 голосов
/ 08 июля 2011

В этом случае вы можете использовать маленький трюк

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

В более общем контексте понятия не имею, сэр ...

EDIT

Я забыл, вам нужно, чтобы processor был implicit, поэтому он не будет компилироваться ...

...