Upload
susan-potter
View
2.350
Download
0
Tags:
Embed Size (px)
DESCRIPTION
In functional programming, words from Category Theory are thrown around, but how useful are they really? This session looks at applications of monoids specifically and how using their algebraic properties offers a solid foundation of reasoning in many types of business domains and reduces developer error as computational context complexity increases. This will provide a tiny peak at Category Theory's practical uses in software development and modeling. Code examples will be in Haskell and Scala, but monoids could be constructed in almost any language by software craftsmen and women utilizing higher orders of reasoning to their code.
Citation preview
Functional AlgebraMonoids Applied
Susan Potter
Nov 10, 2012
OMG, Algebra? FML.. . .
Figure: Chill! Algebra is just a domain specific language
OMG, Algebra? FML.. . .
Figure: Chill! Algebra is just a domain specific language
% whoami
Figure: From OO patterns to FP abstractions
Monoids: What are they?
An abstraction (laws)not a design pattern (forces, context, . . . )
Algebraic structure . . .over a set with a binary operator and an identity element
Accumulator . . .Its sole purpose
Special case category . . .with only one object
Monoids: What are they?
An abstraction (laws)not a design pattern (forces, context, . . . )
Algebraic structure . . .over a set with a binary operator and an identity element
Accumulator . . .Its sole purpose
Special case category . . .with only one object
Monoids: What are they?
An abstraction (laws)not a design pattern (forces, context, . . . )
Algebraic structure . . .over a set with a binary operator and an identity element
Accumulator . . .Its sole purpose
Special case category . . .with only one object
Monoids: What are they?
An abstraction (laws)not a design pattern (forces, context, . . . )
Algebraic structure . . .over a set with a binary operator and an identity element
Accumulator . . .Its sole purpose
Special case category . . .with only one object
Monoids: TypeclassesListing 1: Haskell Monoid Typeclass Definition
1 -- | In Haskell Prelude Data.Monoid2 class Monoid a where3 mempty :: a -- identity4 mappend :: a -> a -> a -- binary op5 mconcat :: [a] -> a -- helper
Listing 2: Scalaz Monoid Trait Definition
1 // Scalaz 7’s Monoid typeclass definition ,kinda2 trait Monoid[A] extends Semigroup[A] { self =>3 def zero: A /* identity */4 def append(x: A, y: => A): A /* binary op */5 }6 // from SemigroupOps[A] ...7 final def |+|(other: => A): A = A.append(self, other)
Monoids: TypeclassesListing 3: Haskell Monoid Typeclass Definition
1 -- | In Haskell Prelude Data.Monoid2 class Monoid a where3 mempty :: a -- identity4 mappend :: a -> a -> a -- binary op5 mconcat :: [a] -> a -- helper
Listing 4: Scalaz Monoid Trait Definition
1 // Scalaz 7’s Monoid typeclass definition ,kinda2 trait Monoid[A] extends Semigroup[A] { self =>3 def zero: A /* identity */4 def append(x: A, y: => A): A /* binary op */5 }6 // from SemigroupOps[A] ...7 final def |+|(other: => A): A = A.append(self, other)
Monoids: TypeclassesListing 5: Haskell Monoid Typeclass Definition
1 -- | In Haskell Prelude Data.Monoid2 class Monoid a where3 mempty :: a -- identity4 mappend :: a -> a -> a -- binary op5 mconcat :: [a] -> a -- helper
Listing 6: Scalaz Monoid Trait Definition
1 // Scalaz 7’s Monoid typeclass definition ,kinda2 trait Monoid[A] extends Semigroup[A] { self =>3 def zero: A /* identity */4 def append(x: A, y: => A): A /* binary op */5 }6 // from SemigroupOps[A] ...7 final def |+|(other: => A): A = A.append(self, other)
Monoids: TypeclassesListing 7: Haskell Monoid Typeclass Definition
1 -- | In Haskell Prelude Data.Monoid2 class Monoid a where3 mempty :: a -- identity4 mappend :: a -> a -> a -- binary op5 mconcat :: [a] -> a -- helper
Listing 8: Scalaz Monoid Trait Definition
1 // Scalaz 7’s Monoid typeclass definition ,kinda2 trait Monoid[A] extends Semigroup[A] { self =>3 def zero: A /* identity */4 def append(x: A, y: => A): A /* binary op */5 }6 // from SemigroupOps[A] ...7 final def |+|(other: => A): A = A.append(self, other)
Monoids: Laws
Closure: ∀a,b ∈ S : ab ∈ Sfor all a and b in set S, the result of a and b given to the binary operatoris also in set S.
Associativity: ∀a,b , c ∈ S : (ab)c = a(bc)for all a, b, and c in set S, either binary operator can be evaluated firstto produce same result.
Identity: ∃e ∈ S : ∀a ∈ S : ea = a = aethere exists an e in set S such that for all a in set S ea evaluates to aand is equal to ae
Monoids: Laws
Closure: ∀a,b ∈ S : ab ∈ Sfor all a and b in set S, the result of a and b given to the binary operatoris also in set S.
Associativity: ∀a,b , c ∈ S : (ab)c = a(bc)for all a, b, and c in set S, either binary operator can be evaluated firstto produce same result.
Identity: ∃e ∈ S : ∀a ∈ S : ea = a = aethere exists an e in set S such that for all a in set S ea evaluates to aand is equal to ae
Monoids: Laws
Closure: ∀a,b ∈ S : ab ∈ Sfor all a and b in set S, the result of a and b given to the binary operatoris also in set S.
Associativity: ∀a,b , c ∈ S : (ab)c = a(bc)for all a, b, and c in set S, either binary operator can be evaluated firstto produce same result.
Identity: ∃e ∈ S : ∀a ∈ S : ea = a = aethere exists an e in set S such that for all a in set S ea evaluates to aand is equal to ae
Monoids: Properties (Haskell)1 -- property based tests for monoid "laws"2 -- does not compile yet; must specify type a3 module Tests where4 import Test.QuickCheck (quickCheck)56 -- closure law verified by type system78 propMonoidAssoc :: Monoid a => a -> a -> a -> Bool9 propMonoidAssoc x y z =
10 mappend (mappend x y) z == mappend x (mappend y z)1112 propMonoidIdent :: Monoid a => a -> Bool13 propMonoidIdent x =14 mappend mempty x == x && mappend x mempty == x
Monoids: Simple "Natural" ExamplesListing 9: Haskell
1 -- OP ID List2 foldr (+) 0 [1,2,3,4] -- 103 foldr (*) 1 [1,2,3,4] -- 244 foldr (++) [] [[1], [1,2]] -- [1,1,2]5 foldr (&&) True [True, False, True] -- False6 foldr (||) False [True, False, True] -- True7
mconcat = foldr mappend mempty
Listing 10: Same in Scala: WTF?
1 List(1,2,3,4).foldRight(0)(_+_) // 102 List(1,2,3,4).foldRight(1)(_*_) // 243 List(List(1),List(1,2)).foldRight(List[Int]())(_++_)4 List(true,false,true).foldRight(true)(_&&_)5 List(true,false,true).foldRight(false)(_||_)
Monoids: Simple "Natural" ExamplesListing 11: Haskell
1 -- OP ID List2 foldr (+) 0 [1,2,3,4] -- 103 foldr (*) 1 [1,2,3,4] -- 244 foldr (++) [] [[1], [1,2]] -- [1,1,2]5 foldr (&&) True [True, False, True] -- False6 foldr (||) False [True, False, True] -- True7
mconcat = foldr mappend mempty
Listing 12: Same in Scala: WTF?
1 List(1,2,3,4).foldRight(0)(_+_) // 102 List(1,2,3,4).foldRight(1)(_*_) // 243 List(List(1),List(1,2)).foldRight(List[Int]())(_++_)4 List(true,false,true).foldRight(true)(_&&_)5 List(true,false,true).foldRight(false)(_||_)
Monoids: Simple "Natural" ExamplesListing 13: Haskell
1 -- OP ID List2 foldr (+) 0 [1,2,3,4] -- 103 foldr (*) 1 [1,2,3,4] -- 244 foldr (++) [] [[1], [1,2]] -- [1,1,2]5 foldr (&&) True [True, False, True] -- False6 foldr (||) False [True, False, True] -- True7
mconcat = foldr mappend mempty
Listing 14: Same in Scala: WTF?
1 List(1,2,3,4).foldRight(0)(_+_) // 102 List(1,2,3,4).foldRight(1)(_*_) // 243 List(List(1),List(1,2)).foldRight(List[Int]())(_++_)4 List(true,false,true).foldRight(true)(_&&_)5 List(true,false,true).foldRight(false)(_||_)
Monoids: Simple "Natural" ExamplesListing 15: Haskell
1 -- OP ID List2 foldr (+) 0 [1,2,3,4] -- 103 foldr (*) 1 [1,2,3,4] -- 244 foldr (++) [] [[1], [1,2]] -- [1,1,2]5 foldr (&&) True [True, False, True] -- False6 foldr (||) False [True, False, True] -- True7 mconcat = foldr mappend mempty
Listing 16: Same in Scala: WTF?
1 List(1,2,3,4).foldRight(0)(_+_) // 102 List(1,2,3,4).foldRight(1)(_*_) // 243 List(List(1),List(1,2)).foldRight(List[Int]())(_++_)4 List(true,false,true).foldRight(true)(_&&_)5 List(true,false,true).foldRight(false)(_||_)
Monoids: Simple "Natural" ExamplesListing 17: Haskell
1 -- OP ID List2 foldr (+) 0 [1,2,3,4] -- 103 foldr (*) 1 [1,2,3,4] -- 244 foldr (++) [] [[1], [1,2]] -- [1,1,2]5 foldr (&&) True [True, False, True] -- False6 foldr (||) False [True, False, True] -- True7 mconcat = foldr mappend mempty
Listing 18: Same in Scala: WTF?
1 List(1,2,3,4).foldRight(0)(_+_) // 102 List(1,2,3,4).foldRight(1)(_*_) // 243 List(List(1),List(1,2)).foldRight(List[Int]())(_++_)4 List(true,false,true).foldRight(true)(_&&_)5 List(true,false,true).foldRight(false)(_||_)
Monoids: Define Your Own (Haskell)Listing 19: Haskell Monoid Definition
1 import Data.Monoid23 data Asset = Cash Int4 | Receivables Int ...5 data Liability = NotesPayable Int6 | AccountsPayable Int ...7 -- naive, but illustrative8 data BalSheet = BalSheet [Asset] [Liability]9
10 instance Monoid BalSheet where11 mempty :: m12 mempty = BalSheet [] []13 mappend :: m -> m -> m14 mappend (BalSheet a1 l1) (BalSheet a2 l2) =15 BalSheet (mappend a1 a2) (mappend l1 l2)
Monoids: Define Your Own (Scala)
Listing 20: Scalaz Monoid Definition
1 import scalaz._; import Scalaz._;23 // naive, but illustrative4 case class Portfolio(positions: Seq[Position])5 object Portfolio {6 implicit val portfolioMonoid =7 new Monoid[Portfolio] {8 def append(p1: Portfolio , p2: Portfolio) =9 Portfolio(append(p1.positions , p2.positions))
10 def zero = Portfolio(Seq.empty)11 }12 }
Monoids: So what?
Properties "Interface"Once you understand one monoid, you understand them all; simplerlayers => simpler tests
Type Safe & Type ExpressiveCan mappend As but not a A and a B where A ! = B andmyCalc :: Monoid a => a -> b
Generic Functionse.g. consolidate = foldr mappend mempty
Highly ApplicableLook around your domain. Do you see Monoids Everywhere™ yet?
Monoids: So what?
Properties "Interface"Once you understand one monoid, you understand them all; simplerlayers => simpler tests
Type Safe & Type ExpressiveCan mappend As but not a A and a B where A ! = B andmyCalc :: Monoid a => a -> b
Generic Functionse.g. consolidate = foldr mappend mempty
Highly ApplicableLook around your domain. Do you see Monoids Everywhere™ yet?
Monoids: So what?
Properties "Interface"Once you understand one monoid, you understand them all; simplerlayers => simpler tests
Type Safe & Type ExpressiveCan mappend As but not a A and a B where A ! = B andmyCalc :: Monoid a => a -> b
Generic Functionse.g. consolidate = foldr mappend mempty
Highly ApplicableLook around your domain. Do you see Monoids Everywhere™ yet?
Monoids: So what?
Properties "Interface"Once you understand one monoid, you understand them all; simplerlayers => simpler tests
Type Safe & Type ExpressiveCan mappend As but not a A and a B where A ! = B andmyCalc :: Monoid a => a -> b
Generic Functionse.g. consolidate = foldr mappend mempty
Highly ApplicableLook around your domain. Do you see Monoids Everywhere™ yet?
Monoids: But . . .
Types With Multiple MonoidsMore boilerplate though usually manageable. e.g.
Listing 21: Haskell Monoid Typeclass Definition
1 import Data.Monoid2 toSums = map Sum3 mconcat $ toSums [1,2,3,4] -- 1045 toAlls = map All6 getAll $ mconcat $ toAlls [True, False, True]
Think!Does it make sense to declare Vector as a Monoid in Haskell?
Monoids: But . . .
Types With Multiple MonoidsMore boilerplate though usually manageable. e.g.
Listing 22: Haskell Monoid Typeclass Definition
1 import Data.Monoid2 toSums = map Sum3 mconcat $ toSums [1,2,3,4] -- 1045 toAlls = map All6 getAll $ mconcat $ toAlls [True, False, True]
Think!Does it make sense to declare Vector as a Monoid in Haskell?
Automatic Optimal Pipelining
http://informatikr.com/2012/redis-pipelining.html
Listing 23: Pipelining in Jedis
1 jedis.pipelined(new PipelineBlock() {2 public void execute() {3 incr("hit_count");4 get("mbbx6spp:repos_count");5 }6 });
Listing 24: Automatic Pipelining in Hedis
1 runRedis conn $ do2 hits <- incr "hit_count"3 repos <- get "mbbx6spp:repos_count"4 liftIO $ print (hits, repos)
Automatic Optimal Pipelining
http://informatikr.com/2012/redis-pipelining.html
Listing 25: Pipelining in Jedis
1 jedis.pipelined(new PipelineBlock() {2 public void execute() {3 incr("hit_count");4 get("mbbx6spp:repos_count");5 }6 });
Listing 26: Automatic Pipelining in Hedis
1 runRedis conn $ do2 hits <- incr "hit_count"3 repos <- get "mbbx6spp:repos_count"4 liftIO $ print (hits, repos)
Monoids: Other Fun Examples
Log Priorities / Filters in bittorrenthttp://jlouisramblings.blogspot.com/2010/02/how-logging-is-performed-in-haskell.html
Associative Alpha Blendinghttp://lukepalmer.wordpress.com/2010/02/05/associative-alpha-blending/
Writer Monad Accumulatorfactorial :: Integer -> Writer (Sum Integer) Integer
Tree in Data.Git module of hit package
Monoids: Other Fun Examples
Log Priorities / Filters in bittorrenthttp://jlouisramblings.blogspot.com/2010/02/how-logging-is-performed-in-haskell.html
Associative Alpha Blendinghttp://lukepalmer.wordpress.com/2010/02/05/associative-alpha-blending/
Writer Monad Accumulatorfactorial :: Integer -> Writer (Sum Integer) Integer
Tree in Data.Git module of hit package
Monoids: Other Fun Examples
Log Priorities / Filters in bittorrenthttp://jlouisramblings.blogspot.com/2010/02/how-logging-is-performed-in-haskell.html
Associative Alpha Blendinghttp://lukepalmer.wordpress.com/2010/02/05/associative-alpha-blending/
Writer Monad Accumulatorfactorial :: Integer -> Writer (Sum Integer) Integer
Tree in Data.Git module of hit package
Monoids: Other Fun Examples
Log Priorities / Filters in bittorrenthttp://jlouisramblings.blogspot.com/2010/02/how-logging-is-performed-in-haskell.html
Associative Alpha Blendinghttp://lukepalmer.wordpress.com/2010/02/05/associative-alpha-blending/
Writer Monad Accumulatorfactorial :: Integer -> Writer (Sum Integer) Integer
Tree in Data.Git module of hit package
Monoids: Relationships
Monoid v => Map k v also monoid
All monoids are semigroupsSemigroup is monoid minus identity requirement
All groups are monoidsMonoid is group minus inverse unary operator requirement
Free StructuresGet (money for nothing? and) monoids for free
Monoids: Relationships
Monoid v => Map k v also monoid
All monoids are semigroupsSemigroup is monoid minus identity requirement
All groups are monoidsMonoid is group minus inverse unary operator requirement
Free StructuresGet (money for nothing? and) monoids for free
Monoids: Relationships
Monoid v => Map k v also monoid
All monoids are semigroupsSemigroup is monoid minus identity requirement
All groups are monoidsMonoid is group minus inverse unary operator requirement
Free StructuresGet (money for nothing? and) monoids for free
Monoids: Relationships
Monoid v => Map k v also monoid
All monoids are semigroupsSemigroup is monoid minus identity requirement
All groups are monoidsMonoid is group minus inverse unary operator requirement
Free StructuresGet (money for nothing? and) monoids for free
Monoids: Relationships
Monads & Monoids
A monad over X is the
monoid in category of endofunctors of X
with binary operator as composition(of endofunctors)
and identity being the identity endofunctor
.
Monoids: Relationships
Monads & MonoidsA monad over X is the
monoid in category of endofunctors of X
with binary operator as composition(of endofunctors)
and identity being the identity endofunctor
.
Monoids: Relationships
Monads & MonoidsA monad over X is the
monoid in category of endofunctors of X
with binary operator as composition(of endofunctors)
and identity being the identity endofunctor
.
Monoids: Relationships
Monads & MonoidsA monad over X is the
monoid in category of endofunctors of X
with binary operator as composition(of endofunctors)
and identity being the identity endofunctor
.
Monoids: Relationships
Monads & MonoidsA monad over X is the
monoid in category of endofunctors of X
with binary operator as composition(of endofunctors)
and identity being the identity endofunctor.
Homework
What is an Endofunctor?
Questions?
Figure: http://www.flickr.com/photos/42682395@N04/
@FunAlgebra@SusanPotter
Bonus: References / ResourcesChannel 9 Lectures (Erik Meijer)http://channel9.msdn.com/Shows/Going+Deep/
Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-1
The Catstershttp://www.youtube.com/thecatsters
Haskell Reddithttp://www.reddit.com/r/haskell/
Haskell Cafehttp://www.haskell.org/mailman/listinfo/haskell-cafe
Scalaz Mailing Listhttps://groups.google.com/forum/?fromgroups#!forum/scalaz