2. 함수 합성
(.): 두 함수를 인자로 받아 두 함수의 합성 함수를 리턴
함
(.) :: (b -> c) -> (a -> b) -> (a -> c)
f . g = x -> f (g x)
odd :: Int -> Bool
odd = not . even
3. $를 이용한 함수 application
($) :: (a -> b) -> a -> b
f $ x = f x
> map ($ 3) [(4+), (10*), (^2), sqrt]
[7.0,30.0,9.0,1.7320508075688772]
($): 함수 f와 인자 a를 받아 f a를 호출함
4. Type synonym
• type String = [Char]
• type Pos = (Int, Int)
origin :: Pos
origin = (0, 0)
left :: Pos -> Pos
left (x, y) = (x-1, y)
5. Type synonym
• type Pair a = (a, a)
mult :: Pair Int -> Int
mult (m, n) = m *n
copy :: a -> Pair a
copy x = (x, x)
6. Type synonym
• Can be nested
• type Trans = Pos -> Pos
• Can't be recursive
• type Tree = (Int, [Tree])
8. Algebraic Data Type
data Answer = Yes | No | Unknown
answers :: [Answer]
answers = [Yes, No, Unknown]
flip :: Answer -> Answer
flip Yes = No
flip No = Yes
flip Unknown = Unknown
9. Algebraic Data Type
data Shape = Circle Float
| Rect Float Float
square :: Float -> Shape
square n = Rect n n
area :: Shape -> Float
area (Circle r) = pi * r^2
area (Rect x y) = x * y
Circle :: Float -> Shape
Rect :: Float -> Float -> Shape
10. 재귀 타입 (Succ)
data Nat = Zero | Succ Nat
Zero -- 0
Succ Zero -- 1
Succ (Succ Zero) -- 2
Succ (Succ (Succ Zero)) -- 3
11. 재귀 타입 (Succ)
nat2int :: Nat -> Int
nat2int Zero = 0
nat2int (Succ n) = 1 + nat2int n
int2nat :: Int -> Nat
int2nat 0 = Zero
int2nat n = Succ (int2nat (n-1))
12. 재귀 타입 (Succ)
-- converting to and from integers
add :: Nat -> Nat -> Nat
add m n = int2nat (nat2int m + nat2int n)
-- using recursion
add Zero n = n
add (Succ m) n = Succ (add m n)
14. 재귀 타입(Expr)
data Expr = Val Int
| Add Expr Expr
| Mul Expr Expr
-- 1 + (2 * 3)
Add (Val 1) (Mul (Val 2) (Val 3))
15. 재귀 타입 (Expr)
size :: Expr -> Int
size (Val n) = 1
size (Add x y) = size x + size y
size (Mul x y) = size x + size y
eval :: Expr -> Int
eval (Var n) = n
eval (Add x y) = eval x + eval y
eval (Mul x y) = eval x * eval y
16. 재귀 타입 (Binary Tree)
data Tree a = Leaf a
| Node (Tree a) a (Tree a)
t: Tree Int
t = Node (Node (Leaf 1) 3 (Leaf 4)) 5
(Node (Leaf 6) 7 (Leaf 9))
17. 재귀 타입 (Binary Tree)
occurs :: Eq a => a -> Tree a -> Bool
occurs x (Leaf y) = x == y
occurs x (Node l y r) = x == y
|| occurs x l
|| occurs x r
18. 재귀 타입 (Binary Tree)
flatten :: Tree a -> [a]
flatten (Leaf x) = [x]
flatten (Node l x r) = flatten l
++ [x]
++ flatten r
19. Algebraic Data Type 요약
종류 예제
Enumeration
data Season = Summer | Winter | Autumn |
Spring
Product data Pair = Pair Int Int
Sum data Shape = Circle Float | Rect Float Float
Polymorphic &
Recursive
data Tree a = Leaf a | Node (Tree a) a (Tree a)
20. Record
data Person = Person { firstName :: String
, lastName :: String
, age :: Int
}
• 각 필드에 이름을 부여
• 필드 이름은 해당 필드 값을 꺼내는 getter 함수가 됨
21. Record 생성 및 getter
> :t Person
Person :: String -> String -> Int -> Person
> :t firstName
firstName :: Person -> String
> :t lastName
lastName :: Person -> String
> :t age
age :: Person -> Int
22. Record
> let p = Person { firstName = "Kwang", lastName =
"Seo", age = 20 }
> firstName p
"Kwang"
> age p
20
26. 타입 클래스
data Expr = Const Int
| Add Expr Expr
instance Eq Expr where
(Const _) == (Add _) = False
(Add _) == (Const _) = False
(Const i) == (Const i') = i == i'
(Add x y) == (Add x' y') == x == x' && y == y'
27. 타입 클래스
class Eq a where
(==), (/=) :: a -> a -> Bool
x/=y = not (x==y)
x==y = not (x/=y)
(==)와 (/=) 중 하나만 구현해도 됨
28. 타입 클래스와 C#/Java 인
터페이스 비교
C#/Java 하스켈
Class -
Interface Type class
Interface member Type-class member
Interface implementation Type-class instance
29. 타입 클래스의 특징
• 구현을 따로 지정
• 구현 타입에 대한 명시적 지정
• 여러 개의 레퍼런스 (binary method)
• 결과 값에 대한 레퍼런스 (static method)
• 멤버에 대한 디폴트 구현
• 여러 개의 타입 인자
30. 타입 클래스 메소드의 종
류
> :t show
(Show a) => a -> String
> :t read
(Read a) => String -> a
> :t (==)
(Eq a) => a -> a -> Bool
• instance: show
• static: read
• binary: (==)
32. IO
• pure expression과 impure action을 구분
• IO a
• 액션을 수행하고 a 타입을 리턴
• 예) IO Char, IO ()
33. 간단한 액션
• getChar :: IO Char
• 키보드에서 문자 하나를 읽어 리턴함
• putChar :: Char -> IO ()
• putChar c는 화면에 문자 c를 출력함
• return :: a -> IO a
• return v는 아무런 액션을 하지 않고 v를 리턴함
34. do 표기법
do 표기법을 이용해 여러 개의 액션을 하나의 액션으로
만들 수 있음
act :: IO (Char, Char)
act = do x <- getChar
getChar
y <- getChar
return (x, y)
35. getLine
getLine :: IO String
getLine = do x <- getChar
if x == 'n' then
return []
else
do xs <- getLine
return (x:xs)
37. Maybe
• 함수의 리턴값이 보장되어 있지 않을 때 사용
> import Data.List
> :t elemIndex
elemIndex :: Eq a => a -> [a] -> Maybe Int
> elemIndex ‘b’ "abc"
Just 1
> elemIndex ‘z’ "abc"
Nothing
38. Maybe의 콘텍스트
• Just 1과 1
• Just "Hello"와 "Hello"
• Just ‘a’와 ‘a’
• Nothing과 에러
39. Maybe
safediv :: Int -> Int -> Maybe Int
safediv _ 0 = Nothing
safediv m n = Just (m `div` n)
safehead :: [a] -> Maybe a
safehead [] = Nothing
safehead xs = Just (head xs)
data Maybe a = Nothing | Just a
40. Higher Order
data RoseTree a = RLeaf a
| RNode [RoseTree a]
data BinTree = BLeaf a
| BNode (Pair (BinTree a))
data Pair a = MkPair a a
41. Higher Order
data RoseTree a = RLeaf a
| RNode ([] (RoseTree a))
data BinTree = BLeaf a
| BNode (Pair (BinTree a))
— [] :: * -> * The list constructor
Syntactic Sugar를 제거하면?
42. Higher Order
data Tree k a = Leaf a
| Node (k (Tree k a))
data RoseTree a = Tree [] a
data BinTree = Tree Pair a
data AnnTree = Tree AnnPair a
data Pair a = P a a
data AnnPair a = AP String a a
변화하는 부분을 인자로 추출하면?
• ‘a’는 type (a :: *)
• ‘k’는 type constructor (k :: * -> *)
43. Higher Order
• Maybe a
• Type
• Kind : *
• Maybe
• Type Constructor
• Kind : * -> *
76. 카테고리
법칙
1. (f . g) . h = f . (g . h)
2. f . id = f
3. id . f = f
class Category cat where
id :: cat a a
(.) :: cat b c -> cat a b -> cat a c
instance Category (->) where
id x = x
(f . g) x = f (g x)
78. Maybe 함수의 합성
• f :: A -> Maybe B
• g :: B -> Maybe C
• g .f
• ERROR!
79. Maybe 함수의 합성
(<=<) :: (b -> Maybe c)
-> (a -> Maybe b)
-> (a -> Maybe c)
(f <=< g) x = case g x of
Just y -> f y
Nothing -> Nothing
return :: (a -> Maybe a)
return = Just
80. 함수 합성과의 비교
id :: (a -> a)
return :: (a -> Maybe a)
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(<=<) :: (b -> Maybe c) -> (a -> Maybe b) -> (a -> Maybe c)
(f . g) x = f (g x)
(f <=< g) x = f =<< (g x)
81. Reader 함수의 합성
• f :: A -> (R -> B)
• g :: B -> (R -> C)
• g . f
• ERROR!
82. Reader 함수의 합성
(<=<) :: (b -> (r -> c))
-> (a -> (r -> b))
-> (a -> (r -> c))
(f <=< g) x = r -> f ((g x) r) r
return :: a -> (r -> a)
return a = r -> a
83. 함수 합성과의 비교
id :: (a -> a)
return :: (a -> (r-> a))
(.) :: (b -> c) -> (a -> b) -> (a -> c)
(<=<) :: (b -> (r -> c)) -> (a -> (r -> b)) -> (a -> (r -> c))
(f . g) x = f (g x)
(f <=< g) x = r -> f ((g x) r) r
84. Kleisli 카테고리
newtype Kleisli m a b =
Kleisli { runKleisli :: a -> m b }
instance Monad m => Category (Kleisli m) where
id = Kleisli return
(Kleisli f) . (Kleisli g) = Kleisli (f <=< g)
85. Kleisli 카테고리와 Monad
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
return :: a -> m a
• (a >>= f) = (f <=< id) a
• (f <=< g) x = f =<< (g x)
86. Kleisli 카테고리로 보는 모
나드 법칙
카테고리 법칙
1. left identity
• return >=> g ≡ g
2. Right Identity
• f >=> return ≡ f
3. Associativity
• (f >=> g) >=> h ≡ f >=> (g >=> h)
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
모나드 법칙
1. left identity
• m >>= return = m
2. Right Identity
• return x >>= f = f x
3. Associativity
• m >>= (y -> g y >>= f) = (m >>= g)
>>= f
87. 모나드의 종류
• Maybe
• Either
• IO
• Reader
• Writer
• State
• Continuation
• Parser
• Pipe
• …
88. Monad의 함의
사이드 이펙트가 있는 함수에 조합성을 주기 위한 구조
Functional Programming
Compositional Programming
90. 참고 자료
1. Slides of Programming in Haskell
• http://www.cs.nott.ac.uk/~pszgmh/book.html
2. Learn You a Haskell for Great Good!
• http://learnyouahaskell.com/chapters
3. A Gentle Introduction to Haskell 98
• https://www.haskell.org/tutorial/haskell-98-tutorial.pdf
4. Slides of Functional systems in Haskell (Stanford CS240h Spring 2014)
• http://www.scs.stanford.edu/14sp-cs240h/slides/
5. Slides of Introduction to Haskell (University of Virginia CS 1501 Lectures Spring 2013)
• http://shuklan.com/haskell/index.html