이건 F# 트리의 모든 자식들의 합을 구하는 예제임.
간단한 문제이고 c언어 수준에서도 큰 어려움없이 구현되지만
다음 코드를 보면 얼마나 직관적이고 인간의 사고구조와 가깝게 표현이 되는지 알 수 있음
먼저 바이너리 트리의 타입을 정하자.
아래는 F#의 discrete union type 문법인데 쉽게 말해서 어떤 타입을 두개의 타입의 조합으로 만들어낼 수 있음
함수형 언어의 algebraic data type 개념과 1:1 매칭되는 부분임
// `a 는 흔한 제네릭 타입 파라미터로 생각하면 됨
type Tree<'a> =
| Node of Tree<'a> * 'a * Tree<'a> // 트리의 브랜치를 튜플로 나타낸것. Tuple(왼쪽 자식 트리, 나의 값, 오른쪽 자식 트리)
| Leaf of 'a // 트리의 끝자락임
한마디로 Tree는 Node 이거나 Leaf 이다. 직관적임
이제 함수를 구현하자
// rec 키워드는 재귀함수(recursive function)를 구현할 때 붙여주는 것. sumTree는 함수이름이고 tree는 argument임.
let rec sumTree tree =
match tree with // 여기부터 패턴매칭의 우아함을 느낄 수 있음
| Leaf value -> value // tree가 Leaf 이면 Leaf의 value를 리턴. 사실상 재귀함수의 종료조건임
| Node (leftTree, value, rightTree) -> (sumTree leftTree) + value + (sumTree rightTree) // tree가 Node이면 왼쪽 트리의 합과 오른쪽 트리의 합을 더하고 자신의 값을 더함.
위 코드를 보면 알겠지만 뭐하나 낭비되는 코드없이 코드 한줄 한줄이 사람의 사고 흐름과 1:1 맵핑이 됨을 알 수 있음
이러니 절차지향이나 객체지향만 맛보다가 패턴매칭의 우아함에 한번 매료되면 함수형 뽕에 취할 수 밖에 없다
lisp -> haskell -> clojure 순으로 할 생각인데 어떻게 생각하시나요? java는 이름만아는데 클로져해도될련지
함수형언어를 공부하고 싶으면 하스켈부터 보는게 좋고 리슾이라고 하면 common lisp을 말하는 거 같은데 clojure를 먼저 공부하는게 더 좋을 거 같음. 문법이 좀더 깔끔하니까