2016-06-26 13 views
5

Ho sempre creduto che gli alias di tipo si espandano sempre al loro tipo originale se necessario. Ma, qui è un piantagraneAlias ​​di tipo Scala interrompe la compatibilità del tipo

def a[P](a: Option[P]) = { 
    type Res = List[P] // result type alias 
    Nil: Res // Replace this line with Nil: List[P] to clear the error 
} 
def b[V](v: V) = a(Some(v)): List[V] 

non riesce con (scastie)

error: type mismatch; 
found : Res (which expands to) List[P] 
required: List[V] 

Si vede che a converte Option[P] => List[P] e, dal momento che b forniture Some[V], a converte Option[V] => List[V] quando b lo chiama. Ma il compilatore dice che il risultato non è compatibile con List[V]. Com'è possibile? L'errore scompare (scastie) se si sostituisce Nil: Res con Nil: List[P] nello a. È necessario eliminare l'alias di tipo per sbarazzarsi dell'errore. Ciò significa che il tipo di alias è il colpevole.

+1

Anche se si tratta di un errore del compilatore, è strano e confuso dichiarare un alias di tipo all'interno di un metodo e utilizzarlo per inferirne il tipo restituito. –

+0

@ m-z L'ho appena usato in [argument parsing recurion] (http://stackoverflow.com/questions/38037089). Dillo che è sbagliato e tu sai molto meglio. In realtà, questo è uno stile di programmazione promosso dal corso Corusera di Oderki. Ti hanno insegnato che se non fai foldLeft, fai una ricorsione. La ricorsione è il cavallo di battaglia che può fare tutto se non ha mezzi speciali per iterare lo spazio di progettazione fornito. La ricorsione significa che si dispone di una funzione di facciata, che accetta chiamate da parte degli utenti, ma l'effettiva attuazione è eseguita dalla funzione ricorsiva "interna". –

+0

Cioè, il modello funzionale di base è 'def facade (args) = {def worker (iterazione, accumulator: ResType): ResType = if (done) acc else {.recursion.}; worker (starting args)}. 'Come vedi,' acc' del worker corrisponde al tipo risultante e sei costretto a dichiarare il tipo di risultato worker in Scala. Cioè, è necessario specificare il tipo di risultato due volte quando si codifica la facciata. Si prega di non mostrare per favore che dopo il DRY è sbagliato in questo schema FP di base e salvarci da cattive pratiche di programmazione. Dì che il lavoratore deve essere dichiarato fuori. Diciamo che il tipo di inferetto dall'interno è un cattivo odore. –

risposta

0

Sono quasi sicuro che si tratta di un bug del compilatore. Gli alias di tipo in Scala dovrebbero espandersi automaticamente e in questo caso il tipo di a viene indicato come [P](Option[P]) => Res, anziché [P](Option[P]) => List[P]. E poiché Res è in un ambito interno, il compilatore non riesce a trovare il tipo corretto di b.