Skip to content

Instantly share code, notes, and snippets.

@nattybear
Last active May 27, 2021 02:50
Show Gist options
  • Save nattybear/04c0ec8e82e45ebbf140a744510ef519 to your computer and use it in GitHub Desktop.
Save nattybear/04c0ec8e82e45ebbf140a744510ef519 to your computer and use it in GitHub Desktop.
하스켈 Functor

이 글은 위키북스 하스켈을 읽고 정리한 것이다.

안에 들어있는 것 바꾸기

함수 map을 이용하면 리스트 안에 들어있는 것들을 바꿀 수 있다.

GHCi> map (+1) [1,2,3]
[2,3,4]

리스트 뿐만 아니라 아래 타입 Tree 안에 들어있는 것도 바꿀 수 있다.

data Tree a
  = Leaf a
  | Branch (Tree a) (Tree a)
  deriving (Show)

타입 Tree 안에 있는 것을 바꾸는 함수 treeMap은 아래와 같다.

treeMap :: (a -> b) -> Tree a -> Tree b
treeMap f (Leaf x) = Leaf (f x)
treeMap f (Branch left right) =
  Branch (treeMap f left) (treeMap f right)

이렇게 리스트나 Tree 같이 자기 안에 들어 있는 것을 바꿀 수 있는 것들을 타입 클래스 Functor라고 한다.

Functor

타입 클래스 Functor는 아래와 같이 정의되어 있다. 함수 fmap만 정의하면 된다.

class Functor f where
  fmap :: (a -> b) -> f a -> f b

함수 fmap의 타입에서 fMaybe로 바꾸면 아래와 같다.

fmap :: (a -> b) -> Maybe a -> Maybe b

타입 MaybeFunctor 인스턴스 정의는 아래와 같다.

instance Functor Maybe where
  fmap f Nothing  = Nothing
  fmap f (Just x) = Just (f x)

타입 리스트의 Functor 인스턴스 정의는 아래와 같다. 그냥 map과 같다.

instance Functor [] where
  fmap = map

위에서 정의한 타입 Tree에 대한 Functor 인스턴스도 아래와 같이 정의할 수 있다.

instance Functor Tree where
  fmap f (Leaf x) = Leaf (f x)
  fmap f (Branch left right) =
    Branch (fmap f left) (fmap f right)

그러니까 사실 위에서처럼 treeMap 같은 함수 이름을 따로 만들 필요는 없는 것이다.

여기서 소개한 것들은 아래와 같이 사용할 수 있다.

GHCi> fmap (2*) [1,2,3,4]
[2,4,6,8]
GHCi> fmap (2*) (Just 1)
Just 2
GHCi> fmap (fmap (2*)) [Just 1, Just 2, Just 3, Nothing]
[Just 2, Just 4, Just 6, Nothing]
GHCi> fmap (2*) (Branch (Branch (Leaf 1) (Leaf 2)) (Branch (Leaf 3) (Leaf 4)))
(Branch (Branch (Leaf 2) (Leaf 4)) (Branch (Leaf 6) (Leaf 8)))

지켜야 할 것

어떤 타입의 Functor 인스턴스를 만들 때는 아래 두가지를 꼭 지켜야 한다.

  • fmap id = id
  • fmap (g . f) = fmap g . fmap f

감회

처음 하스켈을 공부할 때 Learn You a Haskell for Great Good 같은 책을 읽으면서

도대체 Functor가 뭐하는 거지? 뭔소리인지 전혀 모르겠다.

라면서 몇 번이고 같은 페이지를 읽었던 기억이 난다.

지금은 너무 명쾌하고 단순하고 아름다운 개념이라고 생각해서 도대체 쓸 내용이 없다고 까지 생각이 들 정도이다.

지금 뭔가 공부를 하면서 당장 이해가 안 되더라도 조급해 하지 말고 천천히 공부하면 언젠가 깨달을 날이 올 것이다.

대문 링크

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