Je lisais avec Scala 2.8 pour m'amuser et essayais de définir un pimp qui ajoute une méthode "as" pour taper des constructeurs, permettant de convertir d'un foncteur à un autre (veuillez ignorer le fait que je n'ai pas nécessairement affaire à des foncteurs ici). Ainsi, par exemple, vous pouvez l'utiliser comme ceci:"ne peut pas existentiellement abstrait sur type paramétré ..."
val array:Array[T]
val list:List[T] = array.as[List]
Alors, voici ce que j'ai essayé de le faire:
object Test {
abstract class NatTrans[F[_], G[_]] {
def convert[T](f:F[T]):G[T]
}
implicit def array2List:NatTrans[Array, List] = new NatTrans[Array, List] {
def convert[T](a:Array[T]) = a.toList
}
// this next part gets flagged with an error
implicit def naturalTransformations[T, F[_]](f:F[T]) = new {
def as[G[_]](implicit n:NatTrans[F, G]) = n convert f
}
}
cependant la définition de naturalTransformations
est marqué avec l'erreur « ne peut pas existentiellement abstraite sur le type paramétré G [T] ". Pour résoudre ce problème, je peux réécrire naturalTransformations
avec une classe supplémentaire Transformable
comme ceci:
class Transformable[T, F[_]](f:F[T]) {
def as[G[_]](implicit n:NatTrans[F, G]) = n convert f
}
implicit def naturalTransformations[T, F[_]](f:F[T]) = new Transformable[T, F](f)
et il semble fonctionner. Mais il semble que ma première tentative aurait dû être équivalente, alors je suis curieux de savoir pourquoi cela a échoué et ce que signifie le message d'erreur.
J'ai l'habitude de voir l'erreur "Le type de paramètre dans l'affinement structurel peut ne pas faire référence à un type abstrait défini en dehors de ce raffinement" dans des situations similaires. Cette restriction est liée à la façon dont les types structurels sont implémentés sur la JVM avec réflexion, IIRC. http://stackoverflow.com/questions/2685804/scala-parameter-type-in-structural-refinement-may-not-refer-to-an-abstract-type – retronym