Eu entendo por que você quer fazer isso, mas, infelizmente, pode ser apenas uma ilusão que as aulas de Haskell pareçam ser "abertas" da maneira que você diz. Muitas pessoas acham que a possibilidade de fazer isso é um bug na especificação Haskell, pelos motivos que explicarei a seguir. De qualquer forma, se realmente não for apropriado para a instância, você precisa ser declarado no módulo onde a classe é declarada ou no módulo onde o tipo é declarado, provavelmente é um sinal de que você deve usar um newtype
ou algum outro invólucro em torno do seu tipo.
As razões pelas quais as instâncias órfãs precisam ser evitadas são muito mais profundas do que a conveniência do compilador. Este assunto é bastante controverso, como você pode ver nas outras respostas. Para equilibrar a discussão, vou explicar o ponto de vista de que nunca se deve escrever instâncias órfãs, que eu acho que é a opinião da maioria entre os Haskellers experientes. Minha opinião está em algum lugar no meio, o que explicarei no final.
O problema decorre do fato de que, quando mais de uma declaração de instância existe para a mesma classe e tipo, não há mecanismo no Haskell padrão para especificar qual usar. Em vez disso, o programa é rejeitado pelo compilador.
O efeito mais simples disso é que você poderia ter um programa funcionando perfeitamente que iria parar de compilar repentinamente por causa de uma alteração que outra pessoa faz em alguma dependência remota do seu módulo.
Pior ainda, é possível que um programa em funcionamento comece a falhar no tempo de execução devido a uma mudança distante. Você pode estar usando um método que está assumindo que vem de uma determinada declaração de instância e pode ser substituído silenciosamente por uma instância diferente que é diferente o suficiente para fazer com que seu programa comece a falhar inexplicavelmente.
As pessoas que desejam garantias de que esses problemas nunca acontecerão com elas devem seguir a regra de que se alguém, em qualquer lugar, já declarou uma instância de uma determinada classe para um determinado tipo, nenhuma outra instância deve ser declarada novamente em qualquer programa escrito por qualquer um. Obviamente, existe a solução alternativa de usar um newtype
para declarar uma nova instância, mas isso sempre é pelo menos um pequeno inconveniente e, às vezes, um grande inconveniente. Portanto, nesse sentido, aqueles que escrevem instâncias órfãs intencionalmente estão sendo bastante indelicados.
Então, o que deve ser feito sobre esse problema? O campo de instância anti-órfã diz que o aviso do GHC é um bug, precisa ser um erro que rejeita qualquer tentativa de declarar uma instância órfã. Nesse ínterim, devemos exercer autodisciplina e evitá-los a todo custo.
Como você viu, existem aqueles que não estão tão preocupados com esses problemas potenciais. Na verdade, eles encorajam o uso de instâncias órfãs como uma ferramenta para separação de interesses, como você sugere, e dizem que deve-se apenas ter certeza, caso a caso, de que não há problema. Já fui incomodado várias vezes por casos de órfãos de outras pessoas para estar convencido de que essa atitude é muito arrogante.
Acho que a solução certa seria adicionar uma extensão ao mecanismo de importação de Haskell que controlaria a importação de instâncias. Isso não resolveria os problemas completamente, mas ajudaria a proteger nossos programas contra os danos das instâncias órfãs que já existem no mundo. E então, com o tempo, posso me convencer de que, em certos casos limitados, talvez uma instância órfã não seja tão ruim. (E essa mesma tentação é a razão de alguns no campo da instância anti-órfã se oporem à minha proposta.)
Minha conclusão de tudo isso é que, pelo menos por enquanto, eu recomendo fortemente que você evite declarar quaisquer instâncias órfãs, para ter consideração para com os outros, se não por outro motivo. Use um newtype
.