Lo que me gustaría lograr es tener una implementación adecuada paraMixin dinámico en Scala - ¿es posible?
def dynamix[A, B](a: A): A with B
yo sepa qué es B, pero no se que A es (pero si B tiene un auto tipo entonces yo podría añadir un poco restricciones en A). El compilador scala está contento con la firma anterior, pero todavía no podía entender cómo se vería la implementación, si es posible.
Algunas opciones que vienen a la mente:
- Usando la reflexión proxy/dinámico.
- Caso más simple: A es una interfaz en el nivel de Java + Puedo crear una instancia B y no tiene un tipo de auto. Supongo que no sería demasiado difícil (a menos que me encuentre con algunos problemas desagradables e inesperados):
crear un nuevo B (b), y también un proxy implementando A y B y usando un manejador de invocación delegando en a o b . - Si no se puede crear una instancia de B, aún así puedo crear una subclase y hacer lo que se describió anteriormente. Si también tiene un tipo propio, probablemente necesite una delegación aquí y allá, pero aún puede funcionar.
- Pero, ¿qué pasa si A es un tipo concreto y no puedo encontrar una interfaz adecuada para ello?
- ¿Me encontraría con más problemas (por ejemplo, algo relacionado con la linealización o construcciones especiales que ayudan a la interoperabilidad de Java)?
- Caso más simple: A es una interfaz en el nivel de Java + Puedo crear una instancia B y no tiene un tipo de auto. Supongo que no sería demasiado difícil (a menos que me encuentre con algunos problemas desagradables e inesperados):
- Usando un tipo de envoltura en lugar de una mezcla y devuelve B [A], a se puede acceder desde b.
Desafortunadamente, en este caso la persona que llama debería saber cómo se realiza el anidamiento, lo que podría ser bastante inconveniente si la mezcla/envoltura se realiza varias veces (D [C [B [A]]] ya que sería necesario encuentre el nivel correcto de anidación para acceder a la funcionalidad necesaria, por lo que no lo considero una solución. - Implementación de un complemento de compilación. No tengo ninguna experiencia con eso, pero mi instinto es que no sería trivial. Creo que el complemento autoproxy de Kevin Wright tiene un objetivo un poco similar, pero no sería suficiente para mi problema (¿todavía?).
¿Tiene alguna otra idea que pueda funcionar? ¿De qué manera recomendarías? ¿Qué tipo de "desafíos" esperar?
¿O debería olvidarlo, porque no es posible con las restricciones actuales de Scala?
Intención detrás de mi problema: Digamos que tengo un flujo de trabajo empresarial, pero no es demasiado estricto. Algunos pasos tienen un orden fijo, pero otros no, pero al final todos tienen que hacerse (o algunos de ellos son necesarios para un procesamiento posterior).
Un ejemplo un poco más concreto: tengo una A, puedo agregar B y C a ella. No me importa que se haga primero, pero al final necesitaré una A con B con C.
Comentario: No sé demasiado sobre Groovy pero SO apareció this question y supongo que es más o menos de lo que me gustaría, al menos concepcional.
Otro enfoque (no pensado lo suficiente para saber si ello fuera viable): Envolver en un 'Dynamix [A, B]' (o anidado 'Dynamix [A, Dynamix [B, C]]') y desenvolver a través de implicits para descargar cognitivamente el código del cliente. Cada profundidad de anidación debe definirse (sin profundidad arbitraria). Desventaja: no impondrá restricciones de tipo propio ni permitirá la interacción entre tipos a través de los propios tipos. –
+1 por el buen truco, pero tengo la sensación de que todavía correría al menos en un problema: cómo especificar que al final quiero una A con B con C o Dynamix [A, Dynamix [B, C] ] pero no me importa el orden de mezcla? También me alegraría con Dynamix [A, Dynamix [C, B]], y creo que no sería demasiado fácil encontrar una restricción (especialmente hay muchos rasgos que mezclar). Sin embargo, me gusta su comentario, gracias por ello. –
posible duplicado de [Mezcla en un rasgo dinámicamente] (http://stackoverflow.com/questions/10373318/mixing-in-a-trait-dynamically) –