하스켈에서 Either a bToJSON 인스턴스 구현이 약간 애매하다.

json 객체의 키 값으로 "Left""Right"를 넣는 것 같다. 그런 방식으로 사용하는 사람은 거의 없을 것 같은데... 아무튼 그래서 newtype은 쓰지 않고 인스턴스를 오버라이딩 하고 싶은데 대충 찾아보면 인터넷이나 LLM의 첫번째 대답은 OverlappingInstances 확장을 쓰라고 안내하는데 이건 deprecated 됐다. 대신 다음과 같은 프라그마(pragma)를 쓰면 된다.

  • OVERLAPPING
  • OVERLAPPABLE
  • OVERLAPS

프라그마는 확장과 다른데 확장은 확장을 적은 파일 전체에 적용되지만 프라그마는 해당 인스턴스에만 적용된다.

다음과 같이 사용한다.

instance {-# OVERLAPPING #-} ToJSON a => ToJSON (Either Foo a) where
  toJSON = ...

이렇게 하면 고아[1]를 만들었다며 컴파일러가 내 인성을 비난하겠지만 Either a b를 통째로 오버라이딩 한 것도 아니고 별로 문제가 될 것 같진 않다.


  1. 하스켈에서 타입이나 클래스가 정의된 모듈이 아닌 곳에 인스턴스를 선언할 때 그 인스턴스를 Orphan(고아) 인스턴스라고 한다. ↩︎

6

If you have a fediverse account, you can quote this note from your own instance. Search https://hackers.pub/ap/notes/0199d5f0-dd34-7dba-8ffa-30479a590cbe on your instance and quote it. (Note that quoting is not supported in Mastodon.)

이때 막 프라그마 써가면서 Either의 ToJSON 인스턴스를 원하는대로 구현하려고 애썼는데 알고 보니까 더 쉬운 다른 방법이 있었다. 다음과 같이 sumEncoding이라는 옵션을 이용하면 된다.

toJSON = genericToJSON defaultOptions
  { sumEncoding = UntaggedValue }

전에는 이렇게 좋아하는 언어의 소소한 팁을 라이브러리 문서에서 찾았을 때 SNS에 공유하는 게 삶의 낙이었는데 요즘 같은 LLM 에이전트 딸깍 시대에는 이런 게 다 무슨 소용인가 싶어서 우울하다.

7