2017-02-01 19 views
0

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

class Cont[TT](val n : Int) 

trait I[ +Self ] { 
    final def foo[TT >: Self](implicit num : Cont[TT]) = num.n 
} 

trait B extends I[B] 

object B { 
    implicit def Mint : Cont[B] = new Cont[B](53) 
} 

class S extends B with I[S] 

object S{ 
    implicit def HMint : Cont[S] = new Cont[S](54) 
} 

В является «базовым типом», о котором вы будете иметь несколько подклассов (из которых S является примером). Каждый из этих подклассов предоставит несколько имплицитов (как в случае с Cont в примере), по одному для каждого метода, который он хочет специализировать. Если определенный неявный не определен, используется один из B (не показан в коде выше). Методы, которые вы на самом деле хотите вызвать B и его подклассы, определены в значении I, и для каждого из них есть один тип.
Моя проблема заключается в том, что я хочу написать общие функции, принимающие в качестве аргументов коллекцию B или ее подклассов и вызывающие их методы, но я хочу, чтобы вызывались самые специфические импликации. Проблема в том, что иначе, чем переопределение метода, тип «время компиляции» определяет, какой метод будет вызываться. Например:

val s = new S 
val b : B = s 
(b.foo,s.foo) 
res50: (Int, Int) = (53,54) 

Могу ли я написать свои общие функции таким образом, чтобы называться наиболее конкретным методом? Если нет, есть ли небольшие изменения в библиотеке, которые позволили бы это? Наконец, имеет ли шаблон, используемый этой библиотекой имя? Очень сложно найти информацию о шаблоне, имя которого неизвестно.

ответ

1

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

def f(b:B) = b match { 
    case s:S => s.foo 
    case _ => b.foo 
} 
f(new S) // res0: Int = 54 

P.S. Увы, я не знаю, есть ли у этого шаблона имя.

 Смежные вопросы

  • Нет связанных вопросов^_^