SlideShare a Scribd company logo
Haskell
Study
14. useful monads
Writer Monad
이전에 다뤘던 Maybe, List, IO 등의 모나드 외의 많이 쓰이는 다른 유용한 모나드들에 대해
다뤄봅시다. 첫 번째는 Writer 모나드입니다. Writer 모나드는 작업 중간중간에 로그를 남기고 싶을
때 굉장히 유용하게 사용할 수 있습니다.
newtype Writer extra a = Writer { runWriter :: (a, extra) }
instance Monoid extra => Monad (Writer extra) where
	 return a = Writer (a, mempty)
	 Writer (a, e) >>= f =
		let (b, e') = runWriter (f a) in Writer (b, e `mappend` e')
extra타입은 해당 작업의 결과로 인해 발생한 여분의 값(로그 등)의 타입이고 a 타입은 실제
작업하고자 하는 값의 타입입니다.
Writer Monad
Writer 모나드의 return 함수는 계산하고자 하는 값과, extra 타입의 가장 작은 값(mempty)을
묶은 튜플을 반환합니다.
Prelude> runWriter (return 3 :: Writer String Int)
(3, "")
Prelude> runWriter (return 3 :: Writer (Sum Int) Int)
(3, Sum {getSum = 0})
Prelude> runWriter (return 3 :: Writer (Product Int) Int)
(3, Product {getProduct = 1})
runWriter 함수는 Writer 타입의 값을 일반적인 튜플값으로 바꿔주는 역할을 하죠.
Writer Monad
Writer 모나드를 이용해 간단한 로그를 남기는 예제를 작성해봅시다.
import Control.Monad.Writer
logNumber :: Int -> Writer [String] Int
-- Writer가 아니라 writer인 것에 주의. 관련 내용은 Monad Transformer에서 다룹니다.
logNumber x = writer (x, ["Got Number: " ++ show x])
multWithLog :: Writer [String] Int
multWithLog = do
	a <- logNumber 3
	b <- logNumber 5
	 return (a*b)
Prelude> runWriter multWithLog
(15, ["Got Number: 3", "Got Number: 5"])
Writer Monad
앞의 예제와 같이 Writer 모나드를 사용하면 각각의 연산에 대한 결과 로그를 쉽게 남길 수 있다는
것을 알 수 있습니다. 그리고 Writer 모나드에서 유용하게 사용할 수 있는 함수로 tell이라는 함수가
있습니다.
tell :: extra -> Writer extra ()
tell e = writer ((), e)
tell 함수는 위 선언에서 볼 수 있듯이, 실제 연산 값에는 아무런 영향을 미치지 않고 여분의 값에 대해
특정 값을 추가하고 싶을 때 사용하는 함수입니다. 계산 중간중간에 원하는 로그를 삽입하고 싶을 때
사용할 수 있겠죠.
Writer Monad
tell을 활용하여, 두 수의 gcd를 구하는 함수의 연산 과정을 기록해봅시다.
import Control.Monad.Writer
gcdWithLog :: Int -> Int -> Writer [String] Int
gcdWithLog a b
	 | b == 0 = do
		tell ["Finished with " ++ show a]
		return a
	 | otherwise = do
		 tell [show a ++ " mod " ++ show b ++ " = " ++ show (a `mod` b)]
		 gcdWithLog b (a `mod` b)
Writer Monad
gcd 결과 값을 얻고 싶다면 함수를 수행한 Writer 값에서 첫 번째 요소를 가져오면 되고, 계산 로그가
궁금하다면 두 번째 요소를 가져오면 되겠죠.
Prelude> fst $ runWriter (gcdWithLog 8 3)
1
Prelude> snd $ runWriter (gcdWithLog 8 3)
["8 mod 3 = 2", "3 mod 2 = 1", "2 mod 1 = 0", "Finished With 1"]
State Monad
이번엔 State 모나드입니다. State 모나드는 상태의 변화가 필요한 연산을 구현할 때 굉장히
유용하게 쓸 수 있습니다.
newtype State s a = State { runState :: s -> (a,s) }
State s a는 s 타입의 상태와 a 타입의 결과값을 가지는 연산으로 생각할 수 있습니다.
instance Monad (State s) where
	 return x = State $ s -> (x,s)
	 (State h) >>= f = State $ s -> let (a, newState) = h s
											(State g) = f a
									 in g newState
State Monad
return x = State $ s -> (x,s)
코드가 어려울 땐 타입을 기준으로 하나씩 살펴보는 것이 좋습니다.
return 함수는 원래 (Monad m) => a -> m a라는 타입을 갖고 있는데, 이 때 m이 State s이므로
여기서 return 함수는 a -> State s a 라는 타입을 가지게 됩니다. 그래서 return x는 상태 s를
인자로 받아 결과값 x와 상태 s의 튜플을 돌려주는 연산으로 정의됩니다.
State Monad
(State h) >>= f = State $ s -> let (a, newState) = h s
								 (State g) = f a
								 in g newState
State 모나드에서 >>= 함수는 두 개의 stateful한 연산을 이어주는 역할을 한다고 생각하면 됩니다.
역시 타입부터 하나씩 살펴봅시다.
원래 >>= 함수는 (Monad m) => m a -> (a -> m b) -> m b 라는 타입을 갖고 있습니다.
따라서 여기서는 타입이 State s a -> (a -> State s b) -> State s b가 되겠죠.
그리고 State s a의 내부에 저장된 값은 s -> (a,s)라는 타입을 가집니다. 이 타입을 머릿 속에
잘 새겨둔 상태에서 다음 슬라이드들을 따라가봅시다.
State Monad
(State h) >>= f = State $ s -> let (a, newState) = h s
								 (State g) = f a
								 in g newState
우선 결과값은 State 값 생성자로 시작하고, 이 생성자에 람다를 인자로 주고 있습니다. 따라서 이
람다의 타입은 s -> (b,s)가 되어야겠죠.
State Monad
(State h) >>= f = State $ s -> let (a, newState) = h s
								 (State g) = f a
								 in g newState
따라서 람다의 인자 s는 타입 s를 가지게 됩니다(타입 / 값 헷갈리면 안돼요!). 여기서 이제 let ~ in
구문이 나오죠. let 구문 안 쪽의 내용부터 봅시다.
State Monad
(State h) >>= f = State $ s -> let (a, newState) = h s
								 (State g) = f a
								 in g newState
h s의 결과값을 (a, newState)로 나타내고 있습니다. h 함수는 처음에 말했듯이 s -> (a,s)
타입 서명을 갖고 있죠. 따라서 a값은 a 타입, newState값은 s 타입을 갖게 됩니다. 의미 상으로는
주어진 상태 s에 첫번째 stateful한 연산 h를 적용한 결과, 결과값 a와 바뀐 상태 newState를
얻었다고 할 수 있을 겁니다.
State Monad
(State h) >>= f = State $ s -> let (a, newState) = h s
								 (State g) = f a
								 in g newState
이제 그 상태에서 f a의 결과값을 State g로 나타내고 있죠. f 함수는 a -> State s b 타입을
갖고 있으니, g 함수는 s -> (b,s) 타입을 갖게 될 겁니다. 의미적으로는, h 함수를 적용한
결과 얻은 a 값을 이용하는 두 번째 stateful한 연산 g를 f 함수를 이용해 구하는 것으로 생각할 수
있습니다.
State Monad
(State h) >>= f = State $ s -> let (a, newState) = h s
								 (State g) = f a
								 in g newState
그리고 in 이후 구문에서 이렇게 얻은 새로운 stateful 연산 g에 newState를 넘기고 있죠. 그 결과는
g 함수의 타입이 s -> (b,s)이므로 (b,s) 타입이 될겁니다. 즉, 람다는s 타입의 값을 받아 (b,s)
타입을 리턴하고, 그러니 (State h) >>= f 의 최종 결과 타입은 State s b가 되겠죠.
따라서 (State h) >>= f 라는 식은 의미적으로는 stateful한 연산인 h 함수를 수행한 후, 그
결과값을 이용하는 stateful 연산 g에 h를 수행한 후의 현재 상태(newState)를 넘긴 후의 결과
(b,s), 즉 g 함수의 결과로 얻은 b타입의 값과 새로운 상태 s를 얻는 것으로 생각할 수 있죠. 결국 두
개의 stateful한 연산을 자연스럽게 하나로 엮어주게 되는 것입니다.
stack
State 모나드를 활용하는 예제로 stack를 생각해봅시다. stack은 push와 pop이라는 두 가지
연산을 지원합니다. push / pop은 현재의 stateful한 연산이므로 State 모나드를 이용해 구현할 수
있겠죠.
import Control.Monad.State
type Stack a = [a]
--역시 State가 아니라 state인 것에 주의.
push :: a -> State (Stack a) ()
push val = state $ s -> ((), val:s)
pop :: State (Stack a) a
pop = state $ (top:s) -> (top,s)
stack
이제 이렇게 구현한 stack을 한 번 테스트해봅시다.
stackTest :: State (Stack a) (a,a)
stackTest = do
a <- pop
push a
b <- pop
return (a,b)
ghci> runState stackTest [1,2,3]
((1,1),[2,3])
ghci> runState stackTest [5,4,3,2,1]
((5,5),(4,3,2,1))
Random
다른 유용한 State 모나드 활용 예제로는 random이 있습니다. System.Random 모듈에 있는 난수
생성 함수 random은 아래와 같은 타입을 갖고 있죠.
random :: (RandomGen g, Random a) => g -> (a, g)
이 함수는 난수의 시드값 역할을 할 수 있는 RandomGen 타입 클래스에 속하는 타입 g와, Random
타입 클래스에 속하는 타입 a에 대해 g 값을 받아 난수값 a와 그 이후 시드값 g의 튜플 (a,g)를
반환하는 함수입니다. 저 타입으로부터 random이 stateful 한 함수이며 따라서 State 모나드를
활용할 수 있다는 걸 알 수 있죠.
randomSt :: (RandomGen g, Random a) => State g a
randomSt = state random
Random
이제 randomSt 함수를 이용하면 여러 개의 random 값을 손쉽게 얻어낼 수 있습니다.
import System.Random
import Control.Monad.State
threeRandom :: State StdGen (Bool, Bool, Bool)
threeRandom = do
	a <- randomSt
	b <- randomSt
	c <- randomSt
	 return (a,b,c)
ghci> runState threeRandom (mkStdGen 10)
((True, False, False),356856746 2103410263)
Useful functions
모나드를 쓸 때 유용한 함수 몇 가지를 살펴봅시다. 우선 liftM 함수와 ap 함수입니다.
liftM :: (Monad m) => (a -> b) -> m a -> m b
이 함수는 Monad에 대해 동작한다는 점만 다를 뿐 Functor의 fmap과 동일합니다. Monad가
Functor보다 더 나아간 개념이므로 Monad에 대해서도 fmap과 동일한 연산을 수행할 수 있는 것은
당연하겠죠.
ap :: (Monad m) => m (a -> b) -> m a -> m b
ap역시 Monad에 대해 동작한다는 점만 다를 뿐 Applicative Functor의 <*>과 동일합니다.
Useful functions
ghci> liftM (*2) (Just 5)
Just 10
ghci> liftM (*3) Nothing
Nothing
ghci> liftM (*5) [1,2,3]
[5,10,15]
ghci> Just (*2) `ap` Just 4
Just 8
ghci> Nothing `ap` Just 5
Nothing
ghci> [(*2),(+3)] `ap` [1,2,3]
[2,4,6,4,5,6]
Useful functions
다음은 filterM입니다. 고차함수를 다룰 때 나왔던 filter 함수가 list에 대해서만 동작하는 것이었다면,
filterM 함수는 그걸 일반적인 Monad 차원으로 확장시킨 함수입니다. 이 함수의 타입은 아래와
같습니다.
filter :: (a -> Bool) -> [a] -> [a]
filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a]
이 filterM 함수를 사용하면 해당 monad의 컨텍스트와 관련된 filter 함수를 수행할 수 있습니다.
Useful functions
ghci> filterM (_ -> Just True) [1,2,3]
Just [1,2,3]
ghci> filterM (x -> if x == 2 then Just True else Just False) [1,2,3]
Just [2]
ghci> filterM (_ -> Nothing) [1,2,3]
Nothing
위와 같이 Maybe 모나드에 대해 filterM 함수를 쓰면 원래 Maybe 모나드가 가진 컨텍스트인
'실패할 수 있는 연산'이 그대로 적용된다는 걸 알 수 있습니다. Nothing이 하나라도 포함되면
Nothing, 그렇지 않다면 술어함수를 통과한 값만 남기죠. 그렇다면 list 타입에 대한 filterM은 어떻게
동작할까요? 역시 마찬가지로 list 타입이 지닌 컨텍스트인 '비결정성'을 그대로 가지고 동작합니다.
Useful functions
이 비결정성이라는 특징을 이용해 어떤 집합의 멱집합(powerset - 해당 집합의 부분집합으로
이루어진 집합)을 쉽게 구할 수 있습니다.
powerset :: [a] -> [[a]]
powerset = filterM (x -> [True, False])
ghci> powerset [1,2,3]
[[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]]

More Related Content

What's hot

Haskell study 2
Haskell study 2Haskell study 2
Haskell study 2
Nam Hyeonuk
 
Haskell study 1
Haskell study 1Haskell study 1
Haskell study 1
Nam Hyeonuk
 
Haskell study 3
Haskell study 3Haskell study 3
Haskell study 3
Nam Hyeonuk
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Philip Schwarz
 
Applicative Functor
Applicative FunctorApplicative Functor
Applicative Functor
Philip Schwarz
 
Clojure Monad
Clojure MonadClojure Monad
Clojure Monad
Eunmin Kim
 
Polymorphism and its types
Polymorphism and its typesPolymorphism and its types
Polymorphism and its types
Suraj Bora
 
function, storage class and array and strings
 function, storage class and array and strings function, storage class and array and strings
function, storage class and array and strings
Rai University
 
R strings
R   stringsR   strings
Programming with matlab session 5 looping
Programming with matlab session 5 loopingProgramming with matlab session 5 looping
Programming with matlab session 5 looping
Infinity Tech Solutions
 
ג'אווה - תכנות מונחה עצמים - מחלקות פנימיות - רגילות, אנונימיות וסטטיות
ג'אווה - תכנות מונחה עצמים - מחלקות פנימיות - רגילות, אנונימיות וסטטיותג'אווה - תכנות מונחה עצמים - מחלקות פנימיות - רגילות, אנונימיות וסטטיות
ג'אווה - תכנות מונחה עצמים - מחלקות פנימיות - רגילות, אנונימיות וסטטיות
מורן אלקובי
 
Control structures i
Control structures i Control structures i
Control structures i
Ahmad Idrees
 
Polymorphism
PolymorphismPolymorphism
Polymorphism
Ahmed Za'anin
 
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
Philip Schwarz
 
Recursion
RecursionRecursion
Recursion
Malainine Zaid
 
Passing an Array to a Function (ICT Programming)
Passing an Array to a Function (ICT Programming)Passing an Array to a Function (ICT Programming)
Passing an Array to a Function (ICT Programming)Fatima Kate Tanay
 
POINTERS IN C MRS.SOWMYA JYOTHI.pdf
POINTERS IN C MRS.SOWMYA JYOTHI.pdfPOINTERS IN C MRS.SOWMYA JYOTHI.pdf
POINTERS IN C MRS.SOWMYA JYOTHI.pdf
SowmyaJyothi3
 
Ad hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and CatsAd hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and Cats
Philip Schwarz
 

What's hot (20)

Haskell study 2
Haskell study 2Haskell study 2
Haskell study 2
 
Haskell study 1
Haskell study 1Haskell study 1
Haskell study 1
 
Haskell study 3
Haskell study 3Haskell study 3
Haskell study 3
 
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
Nat, List and Option Monoids -from scratch -Combining and Folding -an exampleNat, List and Option Monoids -from scratch -Combining and Folding -an example
Nat, List and Option Monoids - from scratch - Combining and Folding - an example
 
Applicative Functor
Applicative FunctorApplicative Functor
Applicative Functor
 
Clojure Monad
Clojure MonadClojure Monad
Clojure Monad
 
Polymorphism and its types
Polymorphism and its typesPolymorphism and its types
Polymorphism and its types
 
function, storage class and array and strings
 function, storage class and array and strings function, storage class and array and strings
function, storage class and array and strings
 
R strings
R   stringsR   strings
R strings
 
Php1 sesión 6
Php1 sesión 6Php1 sesión 6
Php1 sesión 6
 
Programming with matlab session 5 looping
Programming with matlab session 5 loopingProgramming with matlab session 5 looping
Programming with matlab session 5 looping
 
ג'אווה - תכנות מונחה עצמים - מחלקות פנימיות - רגילות, אנונימיות וסטטיות
ג'אווה - תכנות מונחה עצמים - מחלקות פנימיות - רגילות, אנונימיות וסטטיותג'אווה - תכנות מונחה עצמים - מחלקות פנימיות - רגילות, אנונימיות וסטטיות
ג'אווה - תכנות מונחה עצמים - מחלקות פנימיות - רגילות, אנונימיות וסטטיות
 
Control structures i
Control structures i Control structures i
Control structures i
 
Polymorphism
PolymorphismPolymorphism
Polymorphism
 
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
The Sieve of Eratosthenes - Part II - Genuine versus Unfaithful Sieve - Haske...
 
Recursion
RecursionRecursion
Recursion
 
Passing an Array to a Function (ICT Programming)
Passing an Array to a Function (ICT Programming)Passing an Array to a Function (ICT Programming)
Passing an Array to a Function (ICT Programming)
 
POINTERS IN C MRS.SOWMYA JYOTHI.pdf
POINTERS IN C MRS.SOWMYA JYOTHI.pdfPOINTERS IN C MRS.SOWMYA JYOTHI.pdf
POINTERS IN C MRS.SOWMYA JYOTHI.pdf
 
Functions in C
Functions in CFunctions in C
Functions in C
 
Ad hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and CatsAd hoc Polymorphism using Type Classes and Cats
Ad hoc Polymorphism using Type Classes and Cats
 

Viewers also liked

Telling my retail startup's story w/ pics & graphics
Telling my retail startup's story w/ pics & graphicsTelling my retail startup's story w/ pics & graphics
Telling my retail startup's story w/ pics & graphics
George Arbogust
 
Report Presentation 01.10.2015
Report Presentation 01.10.2015Report Presentation 01.10.2015
Report Presentation 01.10.2015Joanne Quick
 
Modulo de lectura . unidad 3
Modulo de lectura . unidad 3Modulo de lectura . unidad 3
Modulo de lectura . unidad 3
juan perez
 
Reseña literaria de "Itinerario breve" de Blanca Isaza de Jaramillo
Reseña literaria de "Itinerario breve" de Blanca Isaza de JaramilloReseña literaria de "Itinerario breve" de Blanca Isaza de Jaramillo
Reseña literaria de "Itinerario breve" de Blanca Isaza de Jaramillo
Literaturas Abejorraleñas
 
Interacción web
Interacción   webInteracción   web
Interacción web
Esmeralda Cristo
 
Portfolio_Dylan Russ
Portfolio_Dylan RussPortfolio_Dylan Russ
Portfolio_Dylan RussDylan Russ
 
Capital Owners Vs. Workers?
Capital Owners Vs. Workers?Capital Owners Vs. Workers?
Capital Owners Vs. Workers?
George Arbogust
 
하스켈 성능 튜닝
하스켈 성능 튜닝하스켈 성능 튜닝
하스켈 성능 튜닝
민석 이
 
vectores de fuerza
vectores de fuerzavectores de fuerza
vectores de fuerza
Esteban Puga
 
Unit 11 web authoring
Unit 11 web authoringUnit 11 web authoring
Unit 11 web authoringElPatron233
 
üMbrikupalk.nõmme
üMbrikupalk.nõmmeüMbrikupalk.nõmme
üMbrikupalk.nõmmeDi Nõmme
 
はじめてのWordPress勉強会 vol.03 Word Pressの基本操作
はじめてのWordPress勉強会 vol.03 Word Pressの基本操作はじめてのWordPress勉強会 vol.03 Word Pressの基本操作
はじめてのWordPress勉強会 vol.03 Word Pressの基本操作
MoritaMasahiro
 
はじめてのWordPress勉強会 vol.02 Word Pressの導入
はじめてのWordPress勉強会 vol.02 Word Pressの導入はじめてのWordPress勉強会 vol.02 Word Pressの導入
はじめてのWordPress勉強会 vol.02 Word Pressの導入
MoritaMasahiro
 
Age Of Empires II : Age Of Kings Postmotem
Age Of Empires II : Age Of Kings PostmotemAge Of Empires II : Age Of Kings Postmotem
Age Of Empires II : Age Of Kings Postmotem
Nam Hyeonuk
 
はじめてのWordPress勉強会 vol.01 Word Pressの概要
はじめてのWordPress勉強会 vol.01 Word Pressの概要はじめてのWordPress勉強会 vol.01 Word Pressの概要
はじめてのWordPress勉強会 vol.01 Word Pressの概要
MoritaMasahiro
 
Histerectomia total abdominal
Histerectomia total abdominalHisterectomia total abdominal
Histerectomia total abdominal
Jose Luis Gutierrez
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
Nam Hyeonuk
 
Impacto del Diagnostico y Tratamiento oportuno sobre la progresión de la ERC
Impacto del Diagnostico y Tratamiento oportuno sobre la progresión de la ERCImpacto del Diagnostico y Tratamiento oportuno sobre la progresión de la ERC
Impacto del Diagnostico y Tratamiento oportuno sobre la progresión de la ERC
Roberto Coste
 

Viewers also liked (18)

Telling my retail startup's story w/ pics & graphics
Telling my retail startup's story w/ pics & graphicsTelling my retail startup's story w/ pics & graphics
Telling my retail startup's story w/ pics & graphics
 
Report Presentation 01.10.2015
Report Presentation 01.10.2015Report Presentation 01.10.2015
Report Presentation 01.10.2015
 
Modulo de lectura . unidad 3
Modulo de lectura . unidad 3Modulo de lectura . unidad 3
Modulo de lectura . unidad 3
 
Reseña literaria de "Itinerario breve" de Blanca Isaza de Jaramillo
Reseña literaria de "Itinerario breve" de Blanca Isaza de JaramilloReseña literaria de "Itinerario breve" de Blanca Isaza de Jaramillo
Reseña literaria de "Itinerario breve" de Blanca Isaza de Jaramillo
 
Interacción web
Interacción   webInteracción   web
Interacción web
 
Portfolio_Dylan Russ
Portfolio_Dylan RussPortfolio_Dylan Russ
Portfolio_Dylan Russ
 
Capital Owners Vs. Workers?
Capital Owners Vs. Workers?Capital Owners Vs. Workers?
Capital Owners Vs. Workers?
 
하스켈 성능 튜닝
하스켈 성능 튜닝하스켈 성능 튜닝
하스켈 성능 튜닝
 
vectores de fuerza
vectores de fuerzavectores de fuerza
vectores de fuerza
 
Unit 11 web authoring
Unit 11 web authoringUnit 11 web authoring
Unit 11 web authoring
 
üMbrikupalk.nõmme
üMbrikupalk.nõmmeüMbrikupalk.nõmme
üMbrikupalk.nõmme
 
はじめてのWordPress勉強会 vol.03 Word Pressの基本操作
はじめてのWordPress勉強会 vol.03 Word Pressの基本操作はじめてのWordPress勉強会 vol.03 Word Pressの基本操作
はじめてのWordPress勉強会 vol.03 Word Pressの基本操作
 
はじめてのWordPress勉強会 vol.02 Word Pressの導入
はじめてのWordPress勉強会 vol.02 Word Pressの導入はじめてのWordPress勉強会 vol.02 Word Pressの導入
はじめてのWordPress勉強会 vol.02 Word Pressの導入
 
Age Of Empires II : Age Of Kings Postmotem
Age Of Empires II : Age Of Kings PostmotemAge Of Empires II : Age Of Kings Postmotem
Age Of Empires II : Age Of Kings Postmotem
 
はじめてのWordPress勉強会 vol.01 Word Pressの概要
はじめてのWordPress勉強会 vol.01 Word Pressの概要はじめてのWordPress勉強会 vol.01 Word Pressの概要
はじめてのWordPress勉強会 vol.01 Word Pressの概要
 
Histerectomia total abdominal
Histerectomia total abdominalHisterectomia total abdominal
Histerectomia total abdominal
 
Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약Effective c++ chapter 1,2 요약
Effective c++ chapter 1,2 요약
 
Impacto del Diagnostico y Tratamiento oportuno sobre la progresión de la ERC
Impacto del Diagnostico y Tratamiento oportuno sobre la progresión de la ERCImpacto del Diagnostico y Tratamiento oportuno sobre la progresión de la ERC
Impacto del Diagnostico y Tratamiento oportuno sobre la progresión de la ERC
 

Similar to Haskell study 14

자바8 스트림 API 소개
자바8 스트림 API 소개자바8 스트림 API 소개
자바8 스트림 API 소개
beom kyun choi
 
Lua 문법 -함수
Lua 문법 -함수Lua 문법 -함수
Lua 문법 -함수
Jaehoon Lee
 
하스켈 프로그래밍 입문 2
하스켈 프로그래밍 입문 2하스켈 프로그래밍 입문 2
하스켈 프로그래밍 입문 2
Kwang Yul Seo
 
[Swift] Functions
[Swift] Functions[Swift] Functions
[Swift] Functions
Bill Kim
 
함수적 사고 2장
함수적 사고 2장함수적 사고 2장
함수적 사고 2장
HyeonSeok Choi
 
Policy gradient
Policy gradientPolicy gradient
Policy gradient
태영 정
 
Java jungsuk3 ch14_lambda_stream
Java jungsuk3 ch14_lambda_streamJava jungsuk3 ch14_lambda_stream
Java jungsuk3 ch14_lambda_stream
성 남궁
 
나에 첫번째 자바8 람다식 지앤선
나에 첫번째 자바8 람다식   지앤선나에 첫번째 자바8 람다식   지앤선
나에 첫번째 자바8 람다식 지앤선daewon jeong
 
파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409
Yong Joon Moon
 
Matplotlib 기초 이해하기_20160730
Matplotlib 기초 이해하기_20160730Matplotlib 기초 이해하기_20160730
Matplotlib 기초 이해하기_20160730
Yong Joon Moon
 
13장 연산자 오버로딩
13장 연산자 오버로딩13장 연산자 오버로딩
13장 연산자 오버로딩
유석 남
 
SpringCamp 2013 : About Jdk8
SpringCamp 2013 : About Jdk8SpringCamp 2013 : About Jdk8
SpringCamp 2013 : About Jdk8Sangmin Lee
 
Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저
Circulus
 
6 swift 고급함수
6 swift 고급함수6 swift 고급함수
6 swift 고급함수
Changwon National University
 
Surface flingerservice(서피스 상태 변경 및 출력 요청)
Surface flingerservice(서피스 상태 변경 및 출력 요청)Surface flingerservice(서피스 상태 변경 및 출력 요청)
Surface flingerservice(서피스 상태 변경 및 출력 요청)fefe7270
 
함수형 사고 - Functional thinking
함수형 사고 - Functional thinking함수형 사고 - Functional thinking
함수형 사고 - Functional thinking
재문 심
 
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
Aiden Seonghak Hong
 

Similar to Haskell study 14 (20)

자바8 스트림 API 소개
자바8 스트림 API 소개자바8 스트림 API 소개
자바8 스트림 API 소개
 
Lua 문법 -함수
Lua 문법 -함수Lua 문법 -함수
Lua 문법 -함수
 
하스켈 프로그래밍 입문 2
하스켈 프로그래밍 입문 2하스켈 프로그래밍 입문 2
하스켈 프로그래밍 입문 2
 
[Swift] Functions
[Swift] Functions[Swift] Functions
[Swift] Functions
 
함수적 사고 2장
함수적 사고 2장함수적 사고 2장
함수적 사고 2장
 
Policy gradient
Policy gradientPolicy gradient
Policy gradient
 
Java jungsuk3 ch14_lambda_stream
Java jungsuk3 ch14_lambda_streamJava jungsuk3 ch14_lambda_stream
Java jungsuk3 ch14_lambda_stream
 
나에 첫번째 자바8 람다식 지앤선
나에 첫번째 자바8 람다식   지앤선나에 첫번째 자바8 람다식   지앤선
나에 첫번째 자바8 람다식 지앤선
 
파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409파이썬+Operator+이해하기 20160409
파이썬+Operator+이해하기 20160409
 
Matplotlib 기초 이해하기_20160730
Matplotlib 기초 이해하기_20160730Matplotlib 기초 이해하기_20160730
Matplotlib 기초 이해하기_20160730
 
13장 연산자 오버로딩
13장 연산자 오버로딩13장 연산자 오버로딩
13장 연산자 오버로딩
 
SpringCamp 2013 : About Jdk8
SpringCamp 2013 : About Jdk8SpringCamp 2013 : About Jdk8
SpringCamp 2013 : About Jdk8
 
Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저
 
06장 함수
06장 함수06장 함수
06장 함수
 
6 swift 고급함수
6 swift 고급함수6 swift 고급함수
6 swift 고급함수
 
6 function
6 function6 function
6 function
 
Surface flingerservice(서피스 상태 변경 및 출력 요청)
Surface flingerservice(서피스 상태 변경 및 출력 요청)Surface flingerservice(서피스 상태 변경 및 출력 요청)
Surface flingerservice(서피스 상태 변경 및 출력 요청)
 
함수형 사고 - Functional thinking
함수형 사고 - Functional thinking함수형 사고 - Functional thinking
함수형 사고 - Functional thinking
 
2012 Dm 07
2012 Dm 072012 Dm 07
2012 Dm 07
 
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
 

More from Nam Hyeonuk

Next 게임 실전 프로젝트 슬라이드
Next 게임 실전 프로젝트 슬라이드Next 게임 실전 프로젝트 슬라이드
Next 게임 실전 프로젝트 슬라이드
Nam Hyeonuk
 
Haskell study 11
Haskell study 11Haskell study 11
Haskell study 11
Nam Hyeonuk
 
Haskell study 10
Haskell study 10Haskell study 10
Haskell study 10
Nam Hyeonuk
 
Haskell study 7
Haskell study 7Haskell study 7
Haskell study 7
Nam Hyeonuk
 
Haskell study 0
Haskell study 0Haskell study 0
Haskell study 0
Nam Hyeonuk
 
Multi thread
Multi threadMulti thread
Multi thread
Nam Hyeonuk
 
Memory & object pooling
Memory & object poolingMemory & object pooling
Memory & object pooling
Nam Hyeonuk
 
Database
DatabaseDatabase
Database
Nam Hyeonuk
 
Exception&log
Exception&logException&log
Exception&log
Nam Hyeonuk
 
Iocp advanced
Iocp advancedIocp advanced
Iocp advanced
Nam Hyeonuk
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
Nam Hyeonuk
 
Tcp ip & io model
Tcp ip & io modelTcp ip & io model
Tcp ip & io model
Nam Hyeonuk
 
구문과 의미론(정적 의미론까지)
구문과 의미론(정적 의미론까지)구문과 의미론(정적 의미론까지)
구문과 의미론(정적 의미론까지)
Nam Hyeonuk
 
Gpg 1.1
Gpg 1.1Gpg 1.1
Gpg 1.1
Nam Hyeonuk
 
Stl vector, list, map
Stl vector, list, mapStl vector, list, map
Stl vector, list, map
Nam Hyeonuk
 

More from Nam Hyeonuk (15)

Next 게임 실전 프로젝트 슬라이드
Next 게임 실전 프로젝트 슬라이드Next 게임 실전 프로젝트 슬라이드
Next 게임 실전 프로젝트 슬라이드
 
Haskell study 11
Haskell study 11Haskell study 11
Haskell study 11
 
Haskell study 10
Haskell study 10Haskell study 10
Haskell study 10
 
Haskell study 7
Haskell study 7Haskell study 7
Haskell study 7
 
Haskell study 0
Haskell study 0Haskell study 0
Haskell study 0
 
Multi thread
Multi threadMulti thread
Multi thread
 
Memory & object pooling
Memory & object poolingMemory & object pooling
Memory & object pooling
 
Database
DatabaseDatabase
Database
 
Exception&log
Exception&logException&log
Exception&log
 
Iocp advanced
Iocp advancedIocp advanced
Iocp advanced
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
 
Tcp ip & io model
Tcp ip & io modelTcp ip & io model
Tcp ip & io model
 
구문과 의미론(정적 의미론까지)
구문과 의미론(정적 의미론까지)구문과 의미론(정적 의미론까지)
구문과 의미론(정적 의미론까지)
 
Gpg 1.1
Gpg 1.1Gpg 1.1
Gpg 1.1
 
Stl vector, list, map
Stl vector, list, mapStl vector, list, map
Stl vector, list, map
 

Haskell study 14

  • 2. Writer Monad 이전에 다뤘던 Maybe, List, IO 등의 모나드 외의 많이 쓰이는 다른 유용한 모나드들에 대해 다뤄봅시다. 첫 번째는 Writer 모나드입니다. Writer 모나드는 작업 중간중간에 로그를 남기고 싶을 때 굉장히 유용하게 사용할 수 있습니다. newtype Writer extra a = Writer { runWriter :: (a, extra) } instance Monoid extra => Monad (Writer extra) where return a = Writer (a, mempty) Writer (a, e) >>= f = let (b, e') = runWriter (f a) in Writer (b, e `mappend` e') extra타입은 해당 작업의 결과로 인해 발생한 여분의 값(로그 등)의 타입이고 a 타입은 실제 작업하고자 하는 값의 타입입니다.
  • 3. Writer Monad Writer 모나드의 return 함수는 계산하고자 하는 값과, extra 타입의 가장 작은 값(mempty)을 묶은 튜플을 반환합니다. Prelude> runWriter (return 3 :: Writer String Int) (3, "") Prelude> runWriter (return 3 :: Writer (Sum Int) Int) (3, Sum {getSum = 0}) Prelude> runWriter (return 3 :: Writer (Product Int) Int) (3, Product {getProduct = 1}) runWriter 함수는 Writer 타입의 값을 일반적인 튜플값으로 바꿔주는 역할을 하죠.
  • 4. Writer Monad Writer 모나드를 이용해 간단한 로그를 남기는 예제를 작성해봅시다. import Control.Monad.Writer logNumber :: Int -> Writer [String] Int -- Writer가 아니라 writer인 것에 주의. 관련 내용은 Monad Transformer에서 다룹니다. logNumber x = writer (x, ["Got Number: " ++ show x]) multWithLog :: Writer [String] Int multWithLog = do a <- logNumber 3 b <- logNumber 5 return (a*b) Prelude> runWriter multWithLog (15, ["Got Number: 3", "Got Number: 5"])
  • 5. Writer Monad 앞의 예제와 같이 Writer 모나드를 사용하면 각각의 연산에 대한 결과 로그를 쉽게 남길 수 있다는 것을 알 수 있습니다. 그리고 Writer 모나드에서 유용하게 사용할 수 있는 함수로 tell이라는 함수가 있습니다. tell :: extra -> Writer extra () tell e = writer ((), e) tell 함수는 위 선언에서 볼 수 있듯이, 실제 연산 값에는 아무런 영향을 미치지 않고 여분의 값에 대해 특정 값을 추가하고 싶을 때 사용하는 함수입니다. 계산 중간중간에 원하는 로그를 삽입하고 싶을 때 사용할 수 있겠죠.
  • 6. Writer Monad tell을 활용하여, 두 수의 gcd를 구하는 함수의 연산 과정을 기록해봅시다. import Control.Monad.Writer gcdWithLog :: Int -> Int -> Writer [String] Int gcdWithLog a b | b == 0 = do tell ["Finished with " ++ show a] return a | otherwise = do tell [show a ++ " mod " ++ show b ++ " = " ++ show (a `mod` b)] gcdWithLog b (a `mod` b)
  • 7. Writer Monad gcd 결과 값을 얻고 싶다면 함수를 수행한 Writer 값에서 첫 번째 요소를 가져오면 되고, 계산 로그가 궁금하다면 두 번째 요소를 가져오면 되겠죠. Prelude> fst $ runWriter (gcdWithLog 8 3) 1 Prelude> snd $ runWriter (gcdWithLog 8 3) ["8 mod 3 = 2", "3 mod 2 = 1", "2 mod 1 = 0", "Finished With 1"]
  • 8. State Monad 이번엔 State 모나드입니다. State 모나드는 상태의 변화가 필요한 연산을 구현할 때 굉장히 유용하게 쓸 수 있습니다. newtype State s a = State { runState :: s -> (a,s) } State s a는 s 타입의 상태와 a 타입의 결과값을 가지는 연산으로 생각할 수 있습니다. instance Monad (State s) where return x = State $ s -> (x,s) (State h) >>= f = State $ s -> let (a, newState) = h s (State g) = f a in g newState
  • 9. State Monad return x = State $ s -> (x,s) 코드가 어려울 땐 타입을 기준으로 하나씩 살펴보는 것이 좋습니다. return 함수는 원래 (Monad m) => a -> m a라는 타입을 갖고 있는데, 이 때 m이 State s이므로 여기서 return 함수는 a -> State s a 라는 타입을 가지게 됩니다. 그래서 return x는 상태 s를 인자로 받아 결과값 x와 상태 s의 튜플을 돌려주는 연산으로 정의됩니다.
  • 10. State Monad (State h) >>= f = State $ s -> let (a, newState) = h s (State g) = f a in g newState State 모나드에서 >>= 함수는 두 개의 stateful한 연산을 이어주는 역할을 한다고 생각하면 됩니다. 역시 타입부터 하나씩 살펴봅시다. 원래 >>= 함수는 (Monad m) => m a -> (a -> m b) -> m b 라는 타입을 갖고 있습니다. 따라서 여기서는 타입이 State s a -> (a -> State s b) -> State s b가 되겠죠. 그리고 State s a의 내부에 저장된 값은 s -> (a,s)라는 타입을 가집니다. 이 타입을 머릿 속에 잘 새겨둔 상태에서 다음 슬라이드들을 따라가봅시다.
  • 11. State Monad (State h) >>= f = State $ s -> let (a, newState) = h s (State g) = f a in g newState 우선 결과값은 State 값 생성자로 시작하고, 이 생성자에 람다를 인자로 주고 있습니다. 따라서 이 람다의 타입은 s -> (b,s)가 되어야겠죠.
  • 12. State Monad (State h) >>= f = State $ s -> let (a, newState) = h s (State g) = f a in g newState 따라서 람다의 인자 s는 타입 s를 가지게 됩니다(타입 / 값 헷갈리면 안돼요!). 여기서 이제 let ~ in 구문이 나오죠. let 구문 안 쪽의 내용부터 봅시다.
  • 13. State Monad (State h) >>= f = State $ s -> let (a, newState) = h s (State g) = f a in g newState h s의 결과값을 (a, newState)로 나타내고 있습니다. h 함수는 처음에 말했듯이 s -> (a,s) 타입 서명을 갖고 있죠. 따라서 a값은 a 타입, newState값은 s 타입을 갖게 됩니다. 의미 상으로는 주어진 상태 s에 첫번째 stateful한 연산 h를 적용한 결과, 결과값 a와 바뀐 상태 newState를 얻었다고 할 수 있을 겁니다.
  • 14. State Monad (State h) >>= f = State $ s -> let (a, newState) = h s (State g) = f a in g newState 이제 그 상태에서 f a의 결과값을 State g로 나타내고 있죠. f 함수는 a -> State s b 타입을 갖고 있으니, g 함수는 s -> (b,s) 타입을 갖게 될 겁니다. 의미적으로는, h 함수를 적용한 결과 얻은 a 값을 이용하는 두 번째 stateful한 연산 g를 f 함수를 이용해 구하는 것으로 생각할 수 있습니다.
  • 15. State Monad (State h) >>= f = State $ s -> let (a, newState) = h s (State g) = f a in g newState 그리고 in 이후 구문에서 이렇게 얻은 새로운 stateful 연산 g에 newState를 넘기고 있죠. 그 결과는 g 함수의 타입이 s -> (b,s)이므로 (b,s) 타입이 될겁니다. 즉, 람다는s 타입의 값을 받아 (b,s) 타입을 리턴하고, 그러니 (State h) >>= f 의 최종 결과 타입은 State s b가 되겠죠. 따라서 (State h) >>= f 라는 식은 의미적으로는 stateful한 연산인 h 함수를 수행한 후, 그 결과값을 이용하는 stateful 연산 g에 h를 수행한 후의 현재 상태(newState)를 넘긴 후의 결과 (b,s), 즉 g 함수의 결과로 얻은 b타입의 값과 새로운 상태 s를 얻는 것으로 생각할 수 있죠. 결국 두 개의 stateful한 연산을 자연스럽게 하나로 엮어주게 되는 것입니다.
  • 16. stack State 모나드를 활용하는 예제로 stack를 생각해봅시다. stack은 push와 pop이라는 두 가지 연산을 지원합니다. push / pop은 현재의 stateful한 연산이므로 State 모나드를 이용해 구현할 수 있겠죠. import Control.Monad.State type Stack a = [a] --역시 State가 아니라 state인 것에 주의. push :: a -> State (Stack a) () push val = state $ s -> ((), val:s) pop :: State (Stack a) a pop = state $ (top:s) -> (top,s)
  • 17. stack 이제 이렇게 구현한 stack을 한 번 테스트해봅시다. stackTest :: State (Stack a) (a,a) stackTest = do a <- pop push a b <- pop return (a,b) ghci> runState stackTest [1,2,3] ((1,1),[2,3]) ghci> runState stackTest [5,4,3,2,1] ((5,5),(4,3,2,1))
  • 18. Random 다른 유용한 State 모나드 활용 예제로는 random이 있습니다. System.Random 모듈에 있는 난수 생성 함수 random은 아래와 같은 타입을 갖고 있죠. random :: (RandomGen g, Random a) => g -> (a, g) 이 함수는 난수의 시드값 역할을 할 수 있는 RandomGen 타입 클래스에 속하는 타입 g와, Random 타입 클래스에 속하는 타입 a에 대해 g 값을 받아 난수값 a와 그 이후 시드값 g의 튜플 (a,g)를 반환하는 함수입니다. 저 타입으로부터 random이 stateful 한 함수이며 따라서 State 모나드를 활용할 수 있다는 걸 알 수 있죠. randomSt :: (RandomGen g, Random a) => State g a randomSt = state random
  • 19. Random 이제 randomSt 함수를 이용하면 여러 개의 random 값을 손쉽게 얻어낼 수 있습니다. import System.Random import Control.Monad.State threeRandom :: State StdGen (Bool, Bool, Bool) threeRandom = do a <- randomSt b <- randomSt c <- randomSt return (a,b,c) ghci> runState threeRandom (mkStdGen 10) ((True, False, False),356856746 2103410263)
  • 20. Useful functions 모나드를 쓸 때 유용한 함수 몇 가지를 살펴봅시다. 우선 liftM 함수와 ap 함수입니다. liftM :: (Monad m) => (a -> b) -> m a -> m b 이 함수는 Monad에 대해 동작한다는 점만 다를 뿐 Functor의 fmap과 동일합니다. Monad가 Functor보다 더 나아간 개념이므로 Monad에 대해서도 fmap과 동일한 연산을 수행할 수 있는 것은 당연하겠죠. ap :: (Monad m) => m (a -> b) -> m a -> m b ap역시 Monad에 대해 동작한다는 점만 다를 뿐 Applicative Functor의 <*>과 동일합니다.
  • 21. Useful functions ghci> liftM (*2) (Just 5) Just 10 ghci> liftM (*3) Nothing Nothing ghci> liftM (*5) [1,2,3] [5,10,15] ghci> Just (*2) `ap` Just 4 Just 8 ghci> Nothing `ap` Just 5 Nothing ghci> [(*2),(+3)] `ap` [1,2,3] [2,4,6,4,5,6]
  • 22. Useful functions 다음은 filterM입니다. 고차함수를 다룰 때 나왔던 filter 함수가 list에 대해서만 동작하는 것이었다면, filterM 함수는 그걸 일반적인 Monad 차원으로 확장시킨 함수입니다. 이 함수의 타입은 아래와 같습니다. filter :: (a -> Bool) -> [a] -> [a] filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a] 이 filterM 함수를 사용하면 해당 monad의 컨텍스트와 관련된 filter 함수를 수행할 수 있습니다.
  • 23. Useful functions ghci> filterM (_ -> Just True) [1,2,3] Just [1,2,3] ghci> filterM (x -> if x == 2 then Just True else Just False) [1,2,3] Just [2] ghci> filterM (_ -> Nothing) [1,2,3] Nothing 위와 같이 Maybe 모나드에 대해 filterM 함수를 쓰면 원래 Maybe 모나드가 가진 컨텍스트인 '실패할 수 있는 연산'이 그대로 적용된다는 걸 알 수 있습니다. Nothing이 하나라도 포함되면 Nothing, 그렇지 않다면 술어함수를 통과한 값만 남기죠. 그렇다면 list 타입에 대한 filterM은 어떻게 동작할까요? 역시 마찬가지로 list 타입이 지닌 컨텍스트인 '비결정성'을 그대로 가지고 동작합니다.
  • 24. Useful functions 이 비결정성이라는 특징을 이용해 어떤 집합의 멱집합(powerset - 해당 집합의 부분집합으로 이루어진 집합)을 쉽게 구할 수 있습니다. powerset :: [a] -> [[a]] powerset = filterM (x -> [True, False]) ghci> powerset [1,2,3] [[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]]