Slide 1

Slide 1 text

Functional Algebra Monoids Applied Susan Potter Nov 10, 2012

Slide 2

Slide 2 text

OMG, Algebra? FML.. . .

Slide 3

Slide 3 text

OMG, Algebra? FML.. . .

Slide 4

Slide 4 text

% whoami

Slide 5

Slide 5 text

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 • Special case category . . . with only one object

Slide 6

Slide 6 text

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 • Special case category . . . with only one object

Slide 7

Slide 7 text

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 • Special case category . . . with only one object

Slide 8

Slide 8 text

Monoids: Typeclasses Listing 1: Haskell Monoid Typeclass Definition 1 -- | In Haskell Prelude Data.Monoid 2 class Monoid a where 3 mempty :: a -- identity 4 mappend :: a -> a -> a -- binary op 5 mconcat :: [a] -> a -- helper Listing 2: Scalaz Monoid Trait Definition 1 // Scalaz 7’s Monoid typeclass definition ,kinda 2 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)

Slide 9

Slide 9 text

Monoids: Typeclasses Listing 3: Haskell Monoid Typeclass Definition 1 -- | In Haskell Prelude Data.Monoid 2 class Monoid a where 3 mempty :: a -- identity 4 mappend :: a -> a -> a -- binary op 5 mconcat :: [a] -> a -- helper Listing 4: Scalaz Monoid Trait Definition 1 // Scalaz 7’s Monoid typeclass definition ,kinda 2 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)

Slide 10

Slide 10 text

Monoids: Typeclasses Listing 5: Haskell Monoid Typeclass Definition 1 -- | In Haskell Prelude Data.Monoid 2 class Monoid a where 3 mempty :: a -- identity 4 mappend :: a -> a -> a -- binary op 5 mconcat :: [a] -> a -- helper Listing 6: Scalaz Monoid Trait Definition 1 // Scalaz 7’s Monoid typeclass definition ,kinda 2 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)

Slide 11

Slide 11 text

Monoids: Typeclasses Listing 7: Haskell Monoid Typeclass Definition 1 -- | In Haskell Prelude Data.Monoid 2 class Monoid a where 3 mempty :: a -- identity 4 mappend :: a -> a -> a -- binary op 5 mconcat :: [a] -> a -- helper Listing 8: Scalaz Monoid Trait Definition 1 // Scalaz 7’s Monoid typeclass definition ,kinda 2 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)

Slide 12

Slide 12 text

Monoids: Laws • Closure: ∀a, b ∈ S : ab ∈ S for all a and b in set S, the result of a and b given to the binary operator is 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 first to produce same result. • Identity: ∃e ∈ S : ∀a ∈ S : ea = a = ae there exists an e in set S such that for all a in set S ea evaluates to a and is equal to ae

Slide 13

Slide 13 text

Monoids: Laws • Closure: ∀a, b ∈ S : ab ∈ S for all a and b in set S, the result of a and b given to the binary operator is 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 first to produce same result. • Identity: ∃e ∈ S : ∀a ∈ S : ea = a = ae there exists an e in set S such that for all a in set S ea evaluates to a and is equal to ae

Slide 14

Slide 14 text

Monoids: Laws • Closure: ∀a, b ∈ S : ab ∈ S for all a and b in set S, the result of a and b given to the binary operator is 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 first to produce same result. • Identity: ∃e ∈ S : ∀a ∈ S : ea = a = ae there exists an e in set S such that for all a in set S ea evaluates to a and is equal to ae

Slide 15

Slide 15 text

Monoids: Properties (Haskell) 1 -- property based tests for monoid "laws" 2 -- does not compile yet; must specify type a 3 module Tests where 4 import Test.QuickCheck (quickCheck) 5 6 -- closure law verified by type system 7 8 propMonoidAssoc :: Monoid a => a -> a -> a -> Bool 9 propMonoidAssoc x y z = 10 mappend (mappend x y) z == mappend x (mappend y z) 11 12 propMonoidIdent :: Monoid a => a -> Bool 13 propMonoidIdent x = 14 mappend mempty x == x && mappend x mempty == x

Slide 16

Slide 16 text

Monoids: Simple "Natural" Examples Listing 9: Haskell 1 -- OP ID List 2 foldr (+) 0 [1,2,3,4] -- 10 3 foldr (*) 1 [1,2,3,4] -- 24 4 foldr (++) [] [[1], [1,2]] -- [1,1,2] 5 foldr (&&) True [True, False, True] -- False 6 foldr (||) False [True, False, True] -- True 7

Slide 17

Slide 17 text

Monoids: Simple "Natural" Examples Listing 11: Haskell 1 -- OP ID List 2 foldr (+) 0 [1,2,3,4] -- 10 3 foldr (*) 1 [1,2,3,4] -- 24 4 foldr (++) [] [[1], [1,2]] -- [1,1,2] 5 foldr (&&) True [True, False, True] -- False 6 foldr (||) False [True, False, True] -- True 7

Slide 18

Slide 18 text

Monoids: Simple "Natural" Examples Listing 13: Haskell 1 -- OP ID List 2 foldr (+) 0 [1,2,3,4] -- 10 3 foldr (*) 1 [1,2,3,4] -- 24 4 foldr (++) [] [[1], [1,2]] -- [1,1,2] 5 foldr (&&) True [True, False, True] -- False 6 foldr (||) False [True, False, True] -- True 7

Slide 19

Slide 19 text

Monoids: Simple "Natural" Examples Listing 15: Haskell 1 -- OP ID List 2 foldr (+) 0 [1,2,3,4] -- 10 3 foldr (*) 1 [1,2,3,4] -- 24 4 foldr (++) [] [[1], [1,2]] -- [1,1,2] 5 foldr (&&) True [True, False, True] -- False 6 foldr (||) False [True, False, True] -- True 7 mconcat = foldr mappend mempty Listing 16: Same in Scala: WTF? 1 List(1,2,3,4).foldRight(0)(_+_) // 10 2 List(1,2,3,4).foldRight(1)(_*_) // 24 3 List(List(1),List(1,2)).foldRight(List[Int]())(_++_) 4 List(true,false,true).foldRight(true)(_&&_) 5 List(true,false,true).foldRight(false)(_||_)

Slide 20

Slide 20 text

Monoids: Define Your Own (Haskell) Listing 17: Haskell Monoid Definition 1 import Data.Monoid 2 3 data Asset = Cash Int 4 | Receivables Int ... 5 data Liability = NotesPayable Int 6 | AccountsPayable Int ... 7 -- naive, but illustrative 8 data BalSheet = BalSheet [Asset] [Liability] 9 10 instance Monoid BalSheet where 11 mempty :: m 12 mempty = BalSheet [] [] 13 mappend :: m -> m -> m 14 mappend (BalSheet a1 l1) (BalSheet a2 l2) = 15 BalSheet (mappend a1 a2) (mappend l1 l2)

Slide 21

Slide 21 text

Monoids: Define Your Own (Scala) Listing 18: Scalaz Monoid Definition 1 import scalaz._; import Scalaz._; 2 3 // naive, but illustrative 4 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 }

Slide 22

Slide 22 text

Monoids: So what? • Properties "Interface" Once you understand one monoid, you understand them all plus better tests • Type Safe & Type Expressive Can mappend As but not a A and a B where A! = B and myCalc :: Sum a => a -> a • Generic Functions e.g. consolidate = foldr mappend mempty • Highly Applicable Look around your domain. Do you see Monoids Everywhere™ yet?

Slide 23

Slide 23 text

Monoids: So what? • Properties "Interface" Once you understand one monoid, you understand them all plus better tests • Type Safe & Type Expressive Can mappend As but not a A and a B where A! = B and myCalc :: Sum a => a -> a • Generic Functions e.g. consolidate = foldr mappend mempty • Highly Applicable Look around your domain. Do you see Monoids Everywhere™ yet?

Slide 24

Slide 24 text

Monoids: So what? • Properties "Interface" Once you understand one monoid, you understand them all plus better tests • Type Safe & Type Expressive Can mappend As but not a A and a B where A! = B and myCalc :: Sum a => a -> a • Generic Functions e.g. consolidate = foldr mappend mempty • Highly Applicable Look around your domain. Do you see Monoids Everywhere™ yet?

Slide 25

Slide 25 text

Monoids: So what? • Properties "Interface" Once you understand one monoid, you understand them all plus better tests • Type Safe & Type Expressive Can mappend As but not a A and a B where A! = B and myCalc :: Sum a => a -> a • Generic Functions e.g. consolidate = foldr mappend mempty • Highly Applicable Look around your domain. Do you see Monoids Everywhere™ yet?

Slide 26

Slide 26 text

Monoids: But . . . • Types With Multiple Monoids More boilerplate though usually manageable. e.g. Listing 19: Haskell Monoid Typeclass Definition 1 import Data.Monoid (Sum, mconcat) 2 toSums = map Sum 3 mconcat $ toSums [1,2,3,4] • Think! Does it make sense to declare Vector as a Monoid in Haskell?

Slide 27

Slide 27 text

Monoids: But . . . • Types With Multiple Monoids More boilerplate though usually manageable. e.g. Listing 20: Haskell Monoid Typeclass Definition 1 import Data.Monoid (Sum, mconcat) 2 toSums = map Sum 3 mconcat $ toSums [1,2,3,4] • Think! Does it make sense to declare Vector as a Monoid in Haskell?

Slide 28

Slide 28 text

Automatic Optimal Pipelining http://informatikr.com/2012/redis-pipelining.html 1 jedis.pipelined(new PipelineBlock() { 2 public void execute() { 3 incr("hit_count"); 4 get("mbbx6spp:repos_count"); 5 // Do something with values? 6 } 7 }); // Java using Jedis API

Slide 29

Slide 29 text

Automatic Optimal Pipelining http://informatikr.com/2012/redis-pipelining.html 1 jedis.pipelined(new PipelineBlock() { 2 public void execute() { 3 incr("hit_count"); 4 get("mbbx6spp:repos_count"); 5 // Do something with values? 6 } 7 }); // Java using Jedis API 1 -- Haskell using hedis library 2 runRedis conn $ do 3 hits <- incr "hit_count" 4 repos <- get "mbbx6spp:repos_count" 5 -- liftIO $ print (hits, repos)

Slide 30

Slide 30 text

Monoids: Other Fun Examples • Log Priorities / Filters in bittorrent http://jlouisramblings.blogspot.com/2010/02/how-logging-is-performed-in-haskell.html • Associative Alpha Blending http://lukepalmer.wordpress.com/2010/02/05/associative-alpha-blending/ • Tree in Data.Git module of hit package

Slide 31

Slide 31 text

Monoids: Other Fun Examples • Log Priorities / Filters in bittorrent http://jlouisramblings.blogspot.com/2010/02/how-logging-is-performed-in-haskell.html • Associative Alpha Blending http://lukepalmer.wordpress.com/2010/02/05/associative-alpha-blending/ • Tree in Data.Git module of hit package

Slide 32

Slide 32 text

Monoids: Other Fun Examples • Log Priorities / Filters in bittorrent http://jlouisramblings.blogspot.com/2010/02/how-logging-is-performed-in-haskell.html • Associative Alpha Blending http://lukepalmer.wordpress.com/2010/02/05/associative-alpha-blending/ • Tree in Data.Git module of hit package

Slide 33

Slide 33 text

Questions? Figure: http://www.flickr.com/photos/42682395@N04/ @SusanPotter

Slide 34

Slide 34 text

Bonus: References / Resources • Channel 9 Lectures (Erik Meijer) http://channel9.msdn.com/Shows/Going+Deep/ Lecture-Series-Erik-Meijer-Functional-Programming-Fundamentals-Chapter-1 • The Catsters http://www.youtube.com/thecatsters • Haskell Reddit http://www.reddit.com/r/haskell/ • Haskell Cafe http://www.haskell.org/mailman/listinfo/haskell-cafe • Scalaz Mailing List https://groups.google.com/forum/?fromgroups#!forum/scalaz