나는 당신이 이것을하고 싶어하는 이유를 이해합니다. 그러나 불행히도 당신이 말하는 방식으로 하스켈 클래스가 "개방적"인 것처럼 보이는 것은 단지 환상 일 수 있습니다. 많은 사람들이 이것을 할 가능성이 Haskell 사양의 버그라고 생각합니다. 이유는 아래에서 설명하겠습니다. 어쨌든 인스턴스에 실제로 적합하지 않은 경우 클래스가 선언 된 모듈 또는 유형이 선언 된 모듈에서 선언해야합니다. 이는 아마도 newtype
다른 래퍼 를 사용해야한다는 신호일 것입니다. 당신의 유형 주위.
고아 인스턴스를 피해야하는 이유는 컴파일러의 편의성보다 훨씬 더 깊게 실행됩니다. 이 주제는 다른 답변에서 볼 수 있듯이 다소 논란의 여지가 있습니다. 토론의 균형을 맞추기 위해 저는 고아 인스턴스를 절대로 작성해서는 안된다는 관점을 설명하려고합니다. 이는 경험 많은 Haskeller 사이에서 대부분의 의견이라고 생각합니다. 내 의견은 중간 어딘가에 있으며, 마지막에 설명하겠습니다.
문제는 동일한 클래스 및 유형에 대해 둘 이상의 인스턴스 선언이 존재하는 경우 표준 Haskell에 사용할 항목을 지정하는 메커니즘이 없다는 사실에서 기인합니다. 오히려 프로그램은 컴파일러에 의해 거부됩니다.
그것의 가장 간단한 효과는 다른 누군가가 당신의 모듈에 대한 의존성에서 변경 한 변경 때문에 갑자기 컴파일을 멈출 수있는 완벽하게 작동하는 프로그램을 가질 수 있다는 것입니다.
더 나쁜 것은 먼 변경으로 인해 작동중인 프로그램이 런타임에 충돌 을 시작할 수 있다는 것입니다. 특정 인스턴스 선언에서 비롯된 것으로 가정하는 메서드를 사용할 수 있으며 프로그램이 설명 할 수없는 충돌을 일으킬 수있을만큼 다른 인스턴스로 자동으로 대체 될 수 있습니다.
이러한 문제가 발생하지 않는다는 보장을 원하는 사람들은 어느 곳에서나 특정 유형에 대해 특정 클래스의 인스턴스를 선언 한 적이 있다면 작성된 프로그램에서 다른 인스턴스를 다시 선언하지 않아야한다는 규칙을 따라야합니다. 누구든지. 물론 a newtype
를 사용하여 새 인스턴스를 선언하는 해결 방법이 있지만 이는 항상 최소한 사소한 불편이며 때로는 큰 불편입니다. 따라서 이런 의미에서 고아 인스턴스를 의도적으로 작성하는 사람들은 다소 무례합니다.
그렇다면이 문제에 대해 어떻게해야합니까? 안티 고아 인스턴스 캠프는 GHC 경고가 버그이며 고아 인스턴스를 선언하려는 시도를 거부하는 오류 여야한다고 말합니다. 그 동안 우리는 자기 수양을 실천하고 어떤 대가를 치르더라도 피해야합니다.
보시다시피 잠재적 인 문제에 대해 그렇게 걱정하지 않는 사람들이 있습니다. 그들은 실제로 고아 인스턴스를 귀하가 제안한 것처럼 우려 사항 분리 도구로 사용하도록 권장하며 사례별로 문제가 없는지 확인해야한다고 말합니다. 나는 다른 사람들의 고아 사례로 인해 이러한 태도가 너무 무심하다는 것을 확신하기 위해 충분히 불편을 겪었습니다.
올바른 해결책은 인스턴스 가져 오기를 제어하는 Haskell의 가져 오기 메커니즘에 확장을 추가하는 것입니다. 그것은 문제를 완전히 해결하지는 못하지만 이미 세계에 존재하는 고아 인스턴스의 손상으로부터 프로그램을 보호하는 데 도움이 될 것입니다. 그리고 시간이 지남에 따라 특정 제한된 경우에 고아 인스턴스가 그렇게 나쁘지 않을 수 있다고 확신하게 될 것입니다. (그리고 바로 그 유혹이 고아 방지 캠프의 일부가 내 제안에 반대하는 이유입니다.)
이 모든 것에서 내 결론은 적어도 당분간은 고아 인스턴스를 선언하지 말고 다른 이유가없는 경우 다른 사람을 배려하는 것이 좋습니다. 를 사용합니다 newtype
.