monoids

12
Monoids Monoids Piyush Mishra Software Consultant Knoldus Software LLP Piyush Mishra Software Consultant Knoldus Software LLP

Upload: knoldus-software-llp

Post on 31-Oct-2014

2.046 views

Category:

Technology


1 download

DESCRIPTION

Monoids are the certain common pattern followed by the various data types of a programming language. They are the simple algebraic structure governed by certain laws. A  simple monoid consists of a associative operation and an identity element and they can be implemented in the form of trait in scala.

TRANSCRIPT

Page 1: Monoids

MonoidsMonoids

Piyush MishraSoftware Consultant

Knoldus Software LLP

Piyush MishraSoftware Consultant

Knoldus Software LLP

Page 2: Monoids

Topics CoveredTopics CoveredWhat is Monoid

Formal definition of a Monoid

Define a String Monoid

Define a Int Monoid

Define a List Monoid

Fold lists with Monoids

What is Monoid

Formal definition of a Monoid

Define a String Monoid

Define a Int Monoid

Define a List Monoid

Fold lists with Monoids

Page 3: Monoids

What is MonoidWhat is MonoidMonoids are certain common patterns followed by the algebras of various data types of a programming language .

Integers with addition. We know that (a+b)+c == a+(b+c) and 0+n == n+0 == n

same with multiplication: (a*b)*c == a*(b*c) and 1*n == n*1 == n

Strings with concatenation. a+(b+c)==(a+b)+c; ""+s==s and s+"" == s, etc.

Lists with concatenation, like List(1,2)+List(3,4) == List(1,2,3,4)

Sets with their union, like Set(1,2,3)+Set(2,4) == Set(1,2,3,4).

This + binary operation is the common pattern.

Monoids are certain common patterns followed by the algebras of various data types of a programming language .

Integers with addition. We know that (a+b)+c == a+(b+c) and 0+n == n+0 == n

same with multiplication: (a*b)*c == a*(b*c) and 1*n == n*1 == n

Strings with concatenation. a+(b+c)==(a+b)+c; ""+s==s and s+"" == s, etc.

Lists with concatenation, like List(1,2)+List(3,4) == List(1,2,3,4)

Sets with their union, like Set(1,2,3)+Set(2,4) == Set(1,2,3,4).

This + binary operation is the common pattern.

Page 4: Monoids

Formal definition of a monoidFormal definition of a monoidGiven a type A, a binary operation Op:(A,A) => A, and an instance Zero: A, with the properties that will be specified below, the triple (A, Op, Zero) is called a monoid. Here are the properties:

Neutral or identity element : Zero `Op` a == a `Op` Zero == aAssociativity: (a `Op` b) `Op` c == a `Op` (b `Op` c)

We can express this with a Scala trait:

trait Monoid[A] {def op(a1: A, a2: A): Adef zero: A}

Given a type A, a binary operation Op:(A,A) => A, and an instance Zero: A, with the properties that will be specified below, the triple (A, Op, Zero) is called a monoid. Here are the properties:

Neutral or identity element : Zero `Op` a == a `Op` Zero == aAssociativity: (a `Op` b) `Op` c == a `Op` (b `Op` c)

We can express this with a Scala trait:

trait Monoid[A] {def op(a1: A, a2: A): Adef zero: A}

Page 5: Monoids

Define a String monoidDefine a String monoid

trait BaseMonoid[A] { def op(a: A, b: A): A def zero: A}

class StringMonoid extends BaseMonoid[String] { def op(a: String, b: String) = (a.trim + " " + b.trim).trim def zero = ""}

Here we a operation (op) in which we adding two string with space delimiter.

trait BaseMonoid[A] { def op(a: A, b: A): A def zero: A}

class StringMonoid extends BaseMonoid[String] { def op(a: String, b: String) = (a.trim + " " + b.trim).trim def zero = ""}

Here we a operation (op) in which we adding two string with space delimiter.

Page 6: Monoids

Define a Int monoidDefine a Int monoid

trait BaseMonoid[A] { def op(a: A, b: A): A def zero: A}

class IntegerMonoid extends BaseMonoid[Int] { def op(a: Int, b: Int) = a + b def zero = 0}

Here we a operation (op) in which we sum two two integer

trait BaseMonoid[A] { def op(a: A, b: A): A def zero: A}

class IntegerMonoid extends BaseMonoid[Int] { def op(a: Int, b: Int) = a + b def zero = 0}

Here we a operation (op) in which we sum two two integer

Page 7: Monoids

Define a List monoidDefine a List monoid

trait BaseMonoid[A] { def op(a: A, b: A): A def zero: A}

class ListMonoid[A] extends BaseMonoid[List[A]] { def op(a: List[A], b: List[A]): List[A] = a ++ b def zero = Nil}

Here we a operation (op) in which we adding two two Lists

trait BaseMonoid[A] { def op(a: A, b: A): A def zero: A}

class ListMonoid[A] extends BaseMonoid[List[A]] { def op(a: List[A], b: List[A]): List[A] = a ++ b def zero = Nil}

Here we a operation (op) in which we adding two two Lists

Page 8: Monoids

Folding a list with a monoidFolding a list with a monoid

def foldRight(z: A)(f: (A, A) => A): Adef foldLeft(z: A)(f: (A, A) => A): A

val words = List("hello", "world", "Whats Up")

scala> val s = words.foldRight(stringMonoid.zero)(stringMonoid.op)s: String = "hello world Whats Up"scala> val t = words.foldLeft(stringMonoid.zero)(stringMonoid.op)t: String = "hello world Whats Up"

def foldRight(z: A)(f: (A, A) => A): Adef foldLeft(z: A)(f: (A, A) => A): A

val words = List("hello", "world", "Whats Up")

scala> val s = words.foldRight(stringMonoid.zero)(stringMonoid.op)s: String = "hello world Whats Up"scala> val t = words.foldLeft(stringMonoid.zero)(stringMonoid.op)t: String = "hello world Whats Up"

Page 9: Monoids

Function which folds a list with a monoid

Function which folds a list with a monoid

def concatenate[A](as: List[A], m: Monoid[A]): A

def concatenate[A](as: List[A], m: BaseMonoid[A]): A = as.foldRight(m.zero)(m.op)

def concatenate[A](as: List[A], m: Monoid[A]): A

def concatenate[A](as: List[A], m: BaseMonoid[A]): A = as.foldRight(m.zero)(m.op)

Page 10: Monoids

Operation using different monoids instance

Operation using different monoids instance

def foldMap[A,B](as: List[A], m: Monoid[B])(f: A => B): B

def foldMap[A, B](as: List[A], m: Monoid[B])(f: A => B): B = as.foldLeft(m.zero)((b, a) => m.op(b, f(a)))

def foldMap[A,B](as: List[A], m: Monoid[B])(f: A => B): B

def foldMap[A, B](as: List[A], m: Monoid[B])(f: A => B): B = as.foldLeft(m.zero)((b, a) => m.op(b, f(a)))

Page 11: Monoids

Manipulate a json using monoidManipulate a json using monoid val json = """{"first": "John","last": "Doe", "credit_card": 5105105105105100,"ssn": "123-45-6789","salary": 70000, "registered": true }"""

class JsonMonoid extends Monoid[String] { val CREDIT_CARD_REGEX = "\\b\\d{13,16}\\b" val SSN_REGEX = "\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b" val BLOCK_TEXT = "*********"

def identity = "" def op(a1: String, a2: String) = a1 + a2.replaceAll(CREDIT_CARD_REGEX, BLOCK_TEXT).replaceAll(SSN_REGEX, BLOCK_TEXT) + "," }

val monoid = new JsonMonoid val result = json.split(',').foldLeft(monoid.identity)(monoid.op)

val json = """{"first": "John","last": "Doe", "credit_card": 5105105105105100,"ssn": "123-45-6789","salary": 70000, "registered": true }"""

class JsonMonoid extends Monoid[String] { val CREDIT_CARD_REGEX = "\\b\\d{13,16}\\b" val SSN_REGEX = "\\b[0-9]{3}-[0-9]{2}-[0-9]{4}\\b" val BLOCK_TEXT = "*********"

def identity = "" def op(a1: String, a2: String) = a1 + a2.replaceAll(CREDIT_CARD_REGEX, BLOCK_TEXT).replaceAll(SSN_REGEX, BLOCK_TEXT) + "," }

val monoid = new JsonMonoid val result = json.split(',').foldLeft(monoid.identity)(monoid.op)

Page 12: Monoids

Thanks

Thanks