functional algebra: monoids applied

Post on 11-May-2015

2.343 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

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.

TRANSCRIPT

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

top related