2014-12-04 2 views
0

На данный момент у меня есть следующий Scala-код с помощью библиотеки Scala Graph:Декларирование типов на основе типов других значений

val g = Graph.from(nodes, edges) 
      // nodes: List[Table]; edges: List[LkUnDiEdge[Table,String]] 
      // inferred - g: Graph[Table, LkUnDiEdge] 

... 

def nodeTransformer(innerNode: Graph[Table, LkUnDiEdge]#NodeT) = { 
    val node = innerNode.value 
    Some(root, 
      DotNodeStmt(node.name, style(node))) 
} 

Вы можете заметить, что параметр nodeTransformer является внутренним типом типа g , Подобный код повторяет конкретный тип Graph или некоторые его параметры в других местах в кодовой базе.

Ввод типа не работает во всех местах, и я хотел бы выразить эту зависимость типа, не повторяя одинаковые явные типы кода. В качестве примера, оператор C++ typeof позволит мне переписать функцию следующим образом:

def nodeTransformer(innerNode: typeof(g)#NodeT) = { 
    ... 
} 

Что такое нормальный способ выразить такие зависимости статических типов в Scala, когда умозаключение типа потерпит неудачу?

ответ

0

насчет:

def nodeTransformer(innerNode: g.NodeT) = { 
    ... 
} 

В отличие от C++ typeof, вы должны пройти innerNode точно для g, но не какой-либо другой Graph экземпляр (даже с таким же типом): What is meant by Scala's path-dependent types?

P.S. Чтобы извлечь тип из общего (без элемента типа внутри) - How to capture T from TypeTag[T] or any other generic in scala?

+0

Проблема в том, что 'nodeTransformer' передается как параметр другому методу (в частности, как inodeTransformer' из [toDot] (http: // scala-graph .org/guides/dot.html)), и тип этого аргумента должен быть 'Graph [Table, LkUnDiEdge] #NodeT => Option [...]'. 'g.NodeT' несовместим с требуемым типом. – skoy

+0

вы можете попробовать 'innerNode: Graph [g.N, g.E] # NodeT'; N и E недоступны как члены типа, но вы можете их захватить, используя http://stackoverflow.com/questions/26053319/how-to-capture-t-from-typetagt-or-any-other-generic-in-scala – dk14

+0

Как ни странно [этот код] (http://pastebin.com/QX7LaAGc) работает. Я собираюсь отметить этот ответ, как принято. Это что-то вроде убийства с помощью пушки, поэтому я надеюсь, что кто-то может указать более здравый способ добиться такого же эффекта в Скале. – skoy

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