Entiendo por qué quiere hacer esto, pero desafortunadamente ser solo una ilusión de que las clases de Haskell parecen estar "abiertas" en la forma en que dices. Muchas personas sienten que la posibilidad de hacer esto es un error en la especificación Haskell, por razones que explicaré a continuación. De todos modos, si realmente no es apropiado para la instancia que necesita declararse en el módulo donde se declara la clase o en el módulo donde se declara el tipo, es probable que sea una señal de que debe estar usando un newtype
o algún otro envoltorio alrededor de tu tipo.
Las razones por las cuales las instancias huérfanas deben evitarse son mucho más profundas que la conveniencia del compilador. Este tema es bastante controvertido, como puede ver en otras respuestas. Para equilibrar la discusión, voy a explicar el punto de vista de que nunca se deben escribir instancias huérfanas, que creo que es la opinión mayoritaria entre los Haskellers experimentados. Mi propia opinión está en algún punto intermedio, que explicaré al final.
El problema surge del hecho de que cuando existe más de una declaración de instancia para la misma clase y tipo, no existe un mecanismo en Haskell estándar para especificar cuál usar. Más bien, el programa es rechazado por el compilador.
El efecto más simple de eso es que podría tener un programa perfectamente funcional que de repente dejaría de compilar debido a un cambio que alguien más hace en alguna dependencia lejana de su módulo.
Peor aún, es posible que un programa que funcione inicie bloqueándose en el tiempo de ejecución debido a un cambio lejano. Podría estar utilizando un método que está asumiendo que proviene de una declaración de instancia determinada, y podría ser reemplazado silenciosamente por una instancia diferente que sea lo suficientemente diferente como para causar que su programa comience a fallar inexplicablemente.
Las personas que desean garantías de que estos problemas nunca les pasarán deben seguir la regla de que si alguien, en algún lugar, alguna vez ha declarado una clase determinada para cierto tipo, ninguna otra instancia debe ser declarada nuevamente en cualquier programa escrito por cualquier persona. Por supuesto, existe la solución de utilizar un newtype
para declarar una nueva instancia, pero eso siempre es al menos un inconveniente menor, y en ocasiones uno importante. En este sentido, aquellos que escriben intencionalmente instancias huérfanas son bastante descorteses.
Entonces, ¿qué se debe hacer con respecto a este problema? El campo anti-huérfano dice que la advertencia de GHC es un error, debe ser un error que rechace cualquier intento de declarar una instancia huérfana. Mientras tanto, debemos ejercer autodisciplina y evitarlos a toda costa.
Como ha visto, hay quienes no están tan preocupados por esos posibles problemas. De hecho, fomentan el uso de instancias huérfanas como una herramienta para la separación de preocupaciones, como usted sugiere, y dicen que uno debe asegurarse, caso por caso, de que no hay problema. Algunas instancias huérfanas de otras personas me han molestado lo suficiente como para convencerme de que esta actitud es demasiado arrogante.
Creo que la solución correcta sería agregar una extensión al mecanismo de importación de Haskell que controlaría la importación de instancias. Eso no resolvería los problemas por completo, pero ayudaría a proteger nuestros programas contra el daño de las instancias huérfanas que ya existen en el mundo. Y luego, con el tiempo, podría convencerme de que en ciertos casos limitados, quizás una instancia huérfana podría no ser tan mala. (Y esa misma tentación es la razón por la que algunos en el campo antihuérfano se opusieron a mi propuesta.)
Mi conclusión de todo esto es que al menos por el momento, le recomendaría encarecidamente que evite declarar cualquier instancia huérfana, ser considerado con los demás si no es por ninguna otra razón. Use un newtype
.
La discusión en las respuestas y comentarios ilustra que hay una gran diferencia entre la definición de instancias huérfanas en un * ejecutable *, como lo está haciendo, frente a una * biblioteca * que está expuesta a otros. [Esta pregunta tremendamente popular] (http://stackoverflow.com/q/26770247/) ilustra cuán confusas pueden ser las instancias huérfanas para los usuarios finales de una biblioteca que las define. –