2012-11-20 20 views
7

Ho un paio di funzioni il cui unico parametro è che ha una sorta di raccolta che è anche fattibile (cioè potrebbe essere una coda, elenco, prioritàQualità, ecc.), Quindi ho tentato di creare il seguente tipo alias:Errore alias tipo ricorsivo Scala

type Frontier = Growable[Node] with TraversableLike[Node, Frontier] 

da usare con definizioni di funzioni in questo modo:

def apply(frontier: Frontier) = ??? 

ma il tipo alias restituisce l'errore "Illegal riferimento ciclico coinvolge tipo frontiera". C'è un modo per aggirare il riferimento ciclico illegale per usare il tipo alias o qualcosa di simile ad esso?

Una soluzione è quella di utilizzare il seguente:

def apply[F <: Growable[Node] with TraversableLike[Node, F]](f: F) = ??? 

ma questo sembra aggiungere prolissità inutili quando la definizione di funzione sta facendo apparentemente la stessa cosa esatta come tipo di alias. Il tipo viene utilizzato anche in altri luoghi, quindi un alias di tipo aumenterebbe notevolmente la leggibilità.

risposta

6

Dalla sezione 4.3 di the spec:

Le regole di visibilità per le definizioni (§ 4) e parametri di tipo (§4.6) rendono possibile che un nome del tipo viene visualizzato nel proprio legato o nel suo destra lato mano Tuttavia, si tratta di un errore statico se un alias di tipo fa riferimento allo in modo ricorsivo al costruttore del tipo definito stesso.

Quindi no, non c'è modo di farlo direttamente, ma si può fare molto la stessa cosa con un parametro di tipo del tipo alias:

type Frontier[F <: Frontier[F]] = Growable[Int] with TraversableLike[Int, F] 

Ora basta scrivere il vostro apply in questo modo:

Ancora un po 'più verboso della tua ipotetica prima versione, ma più corto di scrivere tutto.

Si potrebbe anche solo utilizzare il jolly scorciatoia per un tipo esistenziale:

type Frontier = Growable[Node] with TraversableLike[Node, _] 

Ora il vostro primo lavoro applysarà così com'è. Stai solo dicendo che ci deve essere il del tipo che si adatta a quello slot, ma non ti interessa quello che è.

In questo caso, tuttavia, esiste un motivo per cui non si sta utilizzando Traversable[Node]? Compirebbe praticamente la stessa cosa e non è parametrizzato sul suo tipo di rappresentazione.

+0

La prima soluzione è ciò che stavo cercando. Il motivo per cui avevo bisogno di questo tipo è fondamentalmente il parametro può essere qualsiasi collezione che posso aggiungere a (quindi Growable), e il tipo di ritorno di molte delle funzioni in Traversable [Node] sarebbe solo Traversable [Node] in contrapposizione a Traversable [ Nodo] con Growable [Node]. In particolare, sto usando le operazioni '+ =', 'head',' tail', 'find' e' filterNot'. È possibile che riformuli il problema per non richiedere '+ =' e quindi non richieda Growable, ma non ho ancora esplorato quella strada. –

+0

Come si dichiara un tipo che è Frontiera? – user1453345

Problemi correlati