3 votes

Pourquoi certains types récursifs ne compilent pas

J'ai rencontré une erreur de vérification des caractères que je n'ai pas pu comprendre. Deux morceaux de code sont identiques, mais un seul compile. Le compilateur donne un message d'erreur totalement inutile :

error : type arguments [I] do not conform to type DY's type parameter bounds [I < : Sample.this.Y]

Le code en question :

trait Sample {
  type X
  type DX[I <: X] <: X
  type Y = Aux[X]
  type DY[I <: Y] <: Y
  type Z = Bux[X]
  type DZ[I <: Z] <: Z
  type DW[I <: Z#C] <: Z#C
}
type Aux[I] = Sample { type X = I }

trait Dep {
  type B
  type C = Aux[B]
}
type Bux[A] = Dep { type B = A }

type UseX[I <: S#X, S <: Sample] = S#DX[I] // ok
type UseY[I <: S#Y, S <: Sample] = S#DY[I] // fails
type UseZ[I <: S#Z, S <: Sample] = S#DZ[I] // ok
type UseW[I <: S#Z#C, S <: Sample] = S#DW[I] // fails

Pourquoi je ne pouvais pas référencer le type lui-même ?


Mise à jour

Je reste aussi confus que lorsque j'ai écrit la question. Mais j'ai quand même réussi à tromper le compilateur pour qu'il fasse son travail. Et cela n'a fait qu'accroître ma confusion.

Le problème est que les arguments de même type sont acceptés ou rejetés sur la base de la liaison de type. Si le type lié est le même que l'argument (introduisant ainsi une récursion), il est rejeté. Mais si j'enveloppe la récursion dans un type, il est accepté normalement. Donc, tout ce dont j'ai besoin, c'est de relayer l'appel à la récursion.

trait Sample {
  type X
  type Y = Aux[X]
  type Z = Bux[X]
  type DY[I <: Y] <: Y
  type DD[I <: Z] = DY[I#C]
}

type UseY[I <: S#Y, S <: Sample] = S#DY[I] // still fails
type UseD[I <: S#Z, S <: Sample] = S#DD[I] // miraculously works

Mais cela nécessite d'envelopper chaque appel au niveau du type dans la balise Bux type d'emballage.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X