SlideShare uma empresa Scribd logo
1 de 31
Baixar para ler offline
Free	Monads
Getting	Started
Self-introduction
	/laʒenɔʁɛ̃k/	カマイルカlagénorhynque
(defprofile lagénorhynque
:name "Kent OHASHI"
:account @lagenorhynque
:company "Opt, Inc."
:languages [Clojure Haskell Python Scala
English français Deutsch русский]
:interests [programming language-learning mathematics]
:contributing [github.com/japan-clojurians/clojure-site-ja])
Contents
1.	 What	are	monads?
2.	 What	are	Free	monads?
3.	 Example:	RPN	expressions
What	are	monads?
de nition	of	Monad
cf.	
GHC.Base#Monad
class Applicative m => Monad m where
(>>=) :: forall a b. m a -> (a -> m b) -> m b
(>>) :: forall a b. m a -> m b -> m b
m >> k = m >>= _ -> k
{-# INLINE (>>) #-}
return :: a -> m a
return = pure
fail :: String -> m a
fail s = errorWithoutStackTrace s
scalaz/Monad.scala
return
値	a	をモナド	m	に⼊れる
Haskell:	return
Scalaz:	point
a	->	m	a
A	=>	M[A]
bind
値	m a	に	関数	a -> m b	を適⽤して	m b	にする
Haskell:	>>=
Scalaz:	bind	(cf.	flatMap)
m	a	->	(a	->	m	b)	->	m	b
M[A]	=>	(A	=>	M[B])	=>	M[B]
do	notation	(Haskell)
↓	desugar
a = Just 2
b = Just 3
c = do
x <- a
y <- b
return $ x * y
a = Just 2
b = Just 3
c = a >>= (x ->
b >>= (y ->
return $ x * y))
for	expression	(Scala)
↓	desugar
val a = Some(2)
val b = Some(3)
val c = for {
x <- a
y <- b
} yield x * y
val a = Some(2)
val b = Some(3)
val c = a.flatMap { x =>
b.map { y =>
x * y
}
}
What	are	Free	monads?
de nition	of	Free
cf.	
Control/Monad/Free.hs
data Free f a = Pure a | Free (f (Free f a))
instance Functor f => Monad (Free f) where
return = pure
{-# INLINE return #-}
Pure a >>= f = f a
Free m >>= f = Free ((>>= f) <$> m)
scalaz/Free.scala
リストのような再帰的データ構造
data [] a = [] | a : [a]
f	が	Functor	⇒	Free f	は	Monad
→	Functor	のインスタンスを	Free	で包めば
Monad	として扱える
※	GHC拡張で	Functor	を⾃動導出することも:
DeriveFunctor
Example:	RPN	expressions
repositories
cf.	
lagenorhynque/freemonad-hs
FreeMonad/RPNExpr.hs
lagenorhynque/freemonad-scala
freemonad/RPNExpr.scala
RPN:	Reverse	Polish	Notation
↓	with	parentheses
↓	evaluate
逆ポーランド記法	-	Wikipedia
8	6	1	-	*	2	+
((8	(6	1	-)	*)	2	+)
42
DSL	interpreter
RPN DSL = AST -- Free monad
→ eval :: AST -> Num
→ stringify :: AST -> String
← parse :: String -> AST
RPNのASTを表現するデータ型	RPNExpr	を定義する
data RPNExpr n expr = Number n expr
| Add expr
| Sub expr
| Mul expr
| End
deriving (Show)
RPNExpr	を	Functor	にする
instance Functor (RPNExpr n) where
fmap f (Number n expr) = Number n $ f expr
fmap f (Add expr) = Add $ f expr
fmap f (Sub expr) = Sub $ f expr
fmap f (Mul expr) = Mul $ f expr
fmap _ End = End
RPNExpr	を	Free	で包んで	RPN Monad	として扱う
type RPN a b = Free (RPNExpr a) b
liftF :: (Functor f) => f r -> Free f r
liftF = Free . fmap Pure
num :: a -> RPN a ()
num n = liftF $ Number n ()
add :: RPN a ()
add = liftF $ Add ()
sub :: RPN a ()
sub = liftF $ Sub ()
mul :: RPN a ()
mul = liftF $ Mul ()
end :: RPN a b
end = liftF End
RPN	モナド(RPNのDSL	=	AST)を試してみる
> :{
| expr1 :: RPN Double ()
| expr1 = do
| num 8
| num 6
| num 1
| sub
| mul
| :}
> expr1
Free (Number 8.0 (Free (Number 6.0 (Free (Number 1.0
(Free (Sub (Free (Mul (Pure ()))))))))))
複数の式を連結してみる
> :{
| expr2 :: RPN Double ()
| expr2 = do
| num 2
| add
| end
| :}
> expr2
Free (Number 2.0 (Free (Add (Free End))))
> expr1 >> expr2
Free (Number 8.0 (Free (Number 6.0 (Free (Number 1.0
(Free (Sub (Free (Mul (Free (Number 2.0 (Free (Add
(Free End))))))))))))))
> :t expr1 >> expr2
expr1 >> expr2 :: Free (RPNExpr Double) () -- RPN Double ()
RPNのASTを⽂字列化する関数	stringify
stringify :: (Show a) => RPN a b -> String
stringify (Free (Number n e)) = show n ++ " " ++ stringify e
stringify (Free (Add e)) = "+ " ++ stringify e
stringify (Free (Sub e)) = "- " ++ stringify e
stringify (Free (Mul e)) = "* " ++ stringify e
stringify (Free End) = "."
stringify (Pure _) = ""
> expr1
Free (Number 8.0 (Free (Number 6.0 (Free (Number 1.0
(Free (Sub (Free (Mul (Pure ()))))))))))
> stringify expr1
"8.0 6.0 1.0 - * "
> expr2
Free (Number 2.0 (Free (Add (Free End))))
> stringify expr2
"2.0 + ."
> stringify $ expr1 >> expr2
"8.0 6.0 1.0 - * 2.0 + ."
⽂字列をRPNのASTに変換する関数	parse
parse :: (Read a) => String -> Either String (RPN a ())
parse = foldM rpn (Pure ()) . reverse . words
where
rpn e "+" = Right . Free $ Add e
rpn e "-" = Right . Free $ Sub e
rpn e "*" = Right . Free $ Mul e
rpn _ "." = Right $ Free End
rpn e n = case reads n of
[(v,_)] -> Right . Free $ Number v e
_ -> Left "invalid input"
> parse "8.0 6.0 1.0 - * " :: Either String (RPN Double ())
Right (Free (Number 8.0 (Free (Number 6.0 (Free (Number 1.0
(Free (Sub (Free (Mul (Pure ())))))))))))
> parse "2.0 + ." :: Either String (RPN Double ())
Right (Free (Number 2.0 (Free (Add (Free End)))))
> parse "8.0 6.0 1.0 - * 2.0 + ." :: Either String (RPN Double ())
Right (Free (Number 8.0 (Free (Number 6.0 (Free (Number 1.0
(Free (Sub (Free (Mul (Free (Number 2.0 (Free (Add
(Free End)))))))))))))))
> parse "2.0 3.0 /" :: Either String (RPN Double ())
Left "invalid input"
RPNのASTを評価する関数	eval
eval :: (Num a) => RPN a b -> Either String a
eval = calc []
where
calc stack (Free (Number n e)) = calc (n : stack) e
calc (n1:n2:ns) (Free (Add e)) = calc (n2 + n1 : ns) e
calc (n1:n2:ns) (Free (Sub e)) = calc (n2 - n1 : ns) e
calc (n1:n2:ns) (Free (Mul e)) = calc (n2 * n1 : ns) e
calc (n:_) (Free End) = Right n
calc (n:_) (Pure _) = Right n
calc _ _ = Left "invalid expression"
> expr1
Free (Number 8.0 (Free (Number 6.0 (Free (Number 1.0
(Free (Sub (Free (Mul (Pure ()))))))))))
> eval expr1
Right 40.0
> expr2
Free (Number 2.0 (Free (Add (Free End))))
> eval expr2
Left "invalid expression"
> eval $ expr1 >> expr2
Right 42.0
データ型を定義して	Functor	にすることで、
Free	を介して	Monad	が得られた
例えば
データ型として定義したASTをモナドに
⇒	合成可能なDSL(=	モナド)が提供できる
⇒	AST(=	モナド)を解釈する関数群を⽤意する
ことでインタプリタが書ける
Further	Reading
/
第13章	外部作⽤とI/O
Haskell	for	all:	Why	free	monads	matter
独習	Scalaz
Free	Monad
猫番
⾃由モナド	(Free)
『Scala関数型デザイン&プログラミング』
Functional	Programming	in	Scala
free:	Monads	for	free
Control/Monad/Free.hs
scalaz/scalaz
scalaz/Free.scala
typelevel/cats
cats/free/Free.scala
/	
10.1	逆ポーランド記法電卓
14.6	安全な逆ポーランド記法電卓を作ろう
cf.	
Interpreter	パターン	-	Wikipedia
『すごいHaskellたのしく学ぼう!』 Learn	You	a
Haskell	for	Great	Good!
MP	in	Scala
MP	in	Haskell
Functor,	Applicative,	Monadのシンプルな定式化

Mais conteúdo relacionado

Mais procurados

Functional programming in Python
Functional programming in PythonFunctional programming in Python
Functional programming in Python
Colin Su
 

Mais procurados (20)

ECSE 221 - Introduction to Computer Engineering - Tutorial 1 - Muhammad Ehtas...
ECSE 221 - Introduction to Computer Engineering - Tutorial 1 - Muhammad Ehtas...ECSE 221 - Introduction to Computer Engineering - Tutorial 1 - Muhammad Ehtas...
ECSE 221 - Introduction to Computer Engineering - Tutorial 1 - Muhammad Ehtas...
 
3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java3. Объекты, классы и пакеты в Java
3. Объекты, классы и пакеты в Java
 
All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!
 
Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)Python Functions (PyAtl Beginners Night)
Python Functions (PyAtl Beginners Night)
 
MTL Versus Free
MTL Versus FreeMTL Versus Free
MTL Versus Free
 
OpenGurukul : Language : PHP
OpenGurukul : Language : PHPOpenGurukul : Language : PHP
OpenGurukul : Language : PHP
 
The best language in the world
The best language in the worldThe best language in the world
The best language in the world
 
Beauty and Power of Go
Beauty and Power of GoBeauty and Power of Go
Beauty and Power of Go
 
Hey! There's OCaml in my Rust!
Hey! There's OCaml in my Rust!Hey! There's OCaml in my Rust!
Hey! There's OCaml in my Rust!
 
Array within a class
Array within a classArray within a class
Array within a class
 
Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 
Swift 2
Swift 2Swift 2
Swift 2
 
Functional programming in Python
Functional programming in PythonFunctional programming in Python
Functional programming in Python
 
Golang iran - tutorial go programming language - Preliminary
Golang iran - tutorial  go programming language - PreliminaryGolang iran - tutorial  go programming language - Preliminary
Golang iran - tutorial go programming language - Preliminary
 
An Intro to Python in 30 minutes
An Intro to Python in 30 minutesAn Intro to Python in 30 minutes
An Intro to Python in 30 minutes
 
Fp201 unit5 1
Fp201 unit5 1Fp201 unit5 1
Fp201 unit5 1
 
OpenGurukul : Language : C++ Programming
OpenGurukul : Language : C++ ProgrammingOpenGurukul : Language : C++ Programming
OpenGurukul : Language : C++ Programming
 
Halogen: Past, Present, and Future
Halogen: Past, Present, and FutureHalogen: Past, Present, and Future
Halogen: Past, Present, and Future
 
Python programming
Python  programmingPython  programming
Python programming
 
OpenGurukul : Language : Python
OpenGurukul : Language : PythonOpenGurukul : Language : Python
OpenGurukul : Language : Python
 

Semelhante a Free Monads Getting Started

Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
Mario Fusco
 
Porque aprender haskell me fez um programador python melhor?
Porque aprender haskell me fez um programador python melhor?Porque aprender haskell me fez um programador python melhor?
Porque aprender haskell me fez um programador python melhor?
UFPA
 
仕事で使うF#
仕事で使うF#仕事で使うF#
仕事で使うF#
bleis tift
 
Swift the implicit parts
Swift the implicit partsSwift the implicit parts
Swift the implicit parts
Maxim Zaks
 
Lecture 5 – Computing with Numbers (Math Lib).pptx
Lecture 5 – Computing with Numbers (Math Lib).pptxLecture 5 – Computing with Numbers (Math Lib).pptx
Lecture 5 – Computing with Numbers (Math Lib).pptx
jovannyflex
 

Semelhante a Free Monads Getting Started (20)

Parsec
ParsecParsec
Parsec
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 
JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java Programmers
 
Day2
Day2Day2
Day2
 
Porque aprender haskell me fez um programador python melhor?
Porque aprender haskell me fez um programador python melhor?Porque aprender haskell me fez um programador python melhor?
Porque aprender haskell me fez um programador python melhor?
 
Kotlin collections
Kotlin collectionsKotlin collections
Kotlin collections
 
仕事で使うF#
仕事で使うF#仕事で使うF#
仕事で使うF#
 
GeoGebra JavaScript CheatSheet
GeoGebra JavaScript CheatSheetGeoGebra JavaScript CheatSheet
GeoGebra JavaScript CheatSheet
 
Real Time Big Data Management
Real Time Big Data ManagementReal Time Big Data Management
Real Time Big Data Management
 
Python programming workshop
Python programming workshopPython programming workshop
Python programming workshop
 
Class 28: Entropy
Class 28: EntropyClass 28: Entropy
Class 28: Entropy
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
 
Monads in Swift
Monads in SwiftMonads in Swift
Monads in Swift
 
iPython
iPythoniPython
iPython
 
Swift the implicit parts
Swift the implicit partsSwift the implicit parts
Swift the implicit parts
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
Parsing swiftly-Cocoaheads-2015-02-12
Parsing swiftly-Cocoaheads-2015-02-12Parsing swiftly-Cocoaheads-2015-02-12
Parsing swiftly-Cocoaheads-2015-02-12
 
Lecture 5 – Computing with Numbers (Math Lib).pptx
Lecture 5 – Computing with Numbers (Math Lib).pptxLecture 5 – Computing with Numbers (Math Lib).pptx
Lecture 5 – Computing with Numbers (Math Lib).pptx
 
Lecture 5 – Computing with Numbers (Math Lib).pptx
Lecture 5 – Computing with Numbers (Math Lib).pptxLecture 5 – Computing with Numbers (Math Lib).pptx
Lecture 5 – Computing with Numbers (Math Lib).pptx
 

Mais de Kent Ohashi

Mais de Kent Ohashi (20)

インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPCインターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
 
Team Geek Revisited
Team Geek RevisitedTeam Geek Revisited
Team Geek Revisited
 
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt TechnologiesScala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
 
Clojureコレクションで探るimmutableでpersistentな世界
Clojureコレクションで探るimmutableでpersistentな世界Clojureコレクションで探るimmutableでpersistentな世界
Clojureコレクションで探るimmutableでpersistentな世界
 
英語学習者のためのフランス語文法入門: フランス語完全理解(?)
英語学習者のためのフランス語文法入門: フランス語完全理解(?)英語学習者のためのフランス語文法入門: フランス語完全理解(?)
英語学習者のためのフランス語文法入門: フランス語完全理解(?)
 
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミングJavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
 
実用のための語源学入門
実用のための語源学入門実用のための語源学入門
実用のための語源学入門
 
メタプログラミング入門
メタプログラミング入門メタプログラミング入門
メタプログラミング入門
 
労働法の世界
労働法の世界労働法の世界
労働法の世界
 
Clojureで作る"simple"なDSL
Clojureで作る"simple"なDSLClojureで作る"simple"なDSL
Clojureで作る"simple"なDSL
 
RDBでのツリー表現入門
RDBでのツリー表現入門RDBでのツリー表現入門
RDBでのツリー表現入門
 
GraphQL入門
GraphQL入門GraphQL入門
GraphQL入門
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.spec
 
たのしい多言語学習
たのしい多言語学習たのしい多言語学習
たのしい多言語学習
 
Ductモジュール入門
Ductモジュール入門Ductモジュール入門
Ductモジュール入門
 
Clojure REPL: The Good Parts
Clojure REPL: The Good PartsClojure REPL: The Good Parts
Clojure REPL: The Good Parts
 
"Simple Made Easy" Made Easy
"Simple Made Easy" Made Easy"Simple Made Easy" Made Easy
"Simple Made Easy" Made Easy
 
Clojurian Conquest
Clojurian ConquestClojurian Conquest
Clojurian Conquest
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixir
 
GraphQL API in Clojure
GraphQL API in ClojureGraphQL API in Clojure
GraphQL API in Clojure
 

Último

Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
VictoriaMetrics
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
masabamasaba
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
chiefasafspells
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
masabamasaba
 

Último (20)

VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?WSO2CON 2024 - Does Open Source Still Matter?
WSO2CON 2024 - Does Open Source Still Matter?
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
WSO2CON 2024 - WSO2's Digital Transformation Journey with Choreo: A Platforml...
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
%+27788225528 love spells in Knoxville Psychic Readings, Attraction spells,Br...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 

Free Monads Getting Started