Skip to content

Instantly share code, notes, and snippets.

@nattybear
Last active May 4, 2022 18:24
Show Gist options
  • Save nattybear/c7981951fc982d496a11b698fbfb3086 to your computer and use it in GitHub Desktop.
Save nattybear/c7981951fc982d496a11b698fbfb3086 to your computer and use it in GitHub Desktop.
2018년 이후에 LYHG을 처음 읽는 사람에게

2018년 이후에 LYHG을 처음 읽는 사람에게

LYHG1은 2011년에 처음 나왔습니다. 출간 당시에 하스켈 컴파일러 GHC 메이저 버전은 7이었습니다.

그런데 2018년에 GHC 8.4.1이 나오면서 SemigroupMonoid의 슈퍼 클래스가 됩니다.

그래서 책에 나온 예제를 그 이후 버전으로 실행 할 경우 에러가 납니다.

책에 나온대로 되지 않으면 진도를 못나가는 저와 같은 완벽주의자를 위해 해결 방법을 소개 합니다.

문제 코드

책 261쪽에 아래와 같은 코드가 나옵니다.

newtype First a = First { getFirst :: Maybe a }
  deriving (Eq, Ord, Read, Show)

instance Monoid (First a) where
  mempty = First Nothing
  First (Just x) `mappend` _ = First (Just x)
  First Nothing  `mappend` x = x

이 코드를 GHC 8.4.1 이후 버전으로 실행하면 아래와 같은 에러가 납니다.

    • No instance for (Semigroup (First a))
        arising from the superclasses of an instance declaration
    • In the instance declaration for ‘Monoid (First a)’

Monoid 인스턴스를 정의 하려면 먼저 Semigroup 인스턴스부터 정의 해야 한다는 말입니다.

해결 방법은 크게 아래와 같이 두 가지가 있습니다.

  • Semigroup 인스턴스를 먼저 정의 한다.
  • 옛날 버전을 사용 한다.

Semigroup 인스턴스 먼저 정의 하기

아래처럼 Monoid 인스턴스를 정의 하기 전에 먼저 Semigroup 인스턴스를 정의 하면 더 이상 에러가 나지 않습니다.

newtype First a = First { getFirst :: Maybe a }
  deriving (Eq, Ord, Read, Show)

instance Semigroup (First a) where
  First (Just x) <> _ = First (Just x)
  First Nothing  <> x = x

instance Monoid (First a) where
  mempty = First Nothing

옛날 버전 사용 하기

GHC 8.4.1 이전 버전을 사용하면 책에 나온대로 할 수 있습니다.

ghcup 같은 도구를 이용하면 쉽게 GHC 버전을 전환 할 수 있어 편리합니다.

대문 링크

Footnotes

  1. Learn You a Haskell for Great Good!의 줄임말

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment