Monday, February 27, 2012

Having Fun with Monoid in Scalaz Seven

It's been some times since my last blog on Scalaz Seven that talks about Functor. You may have guessed that my second post on the series would be Applicative Functor. Well, sorry, I can't write in order yet, I prefer to talk about Monoid in Scalaz Seven instead. OK Let's have fun.

Having Fun With |+|
To start with, let's have some fun with |+| operator.

Let's start

scala> 6 |+| 7
res0: Int = 13

Well, not that interesting. It's just an addition. What about

scala> 6 + "9"
res2: String = 69

scala> 6 |+| "9"
<console>:14: error: type mismatch;
 found   : java.lang.String("9")
 required: Int
       6 |+| "9"

Not bad. |+| somehow protects you from adding integer to String. OK, not bad, but, not that fun. What about this:

scala> some(6) |+| some(9)
res9: Option[Int] = Some(15)

All right, that starts to be interesting. Give me more:

scala> some(6) |+| some(9) |+| some(10)
res10: Option[Int] = Some(25)

scala> some(6) |+| some(9) |+| some(10) |+| none[Int] |+| some(6)
res11: Option[Int] = Some(31)

Not bad at all. Want something more than that. Some String ?

scala> "Hello" |+| "World"

res25: java.lang.String = HelloWorld

scala> some("Hello") |+| some("World")

res26: java.lang.String = Some(HelloWorld)

What else do you have ? List ?

scala> List(2,4) |+| List(4, 5)
res28: List[Int] = List(2, 4, 4,5)

Cool. Boolean?

scala> val b = true
b: Boolean = true

scala> val c = true
c: Boolean = true

scala> b |+| c
<console>:24: error: value |+| is not a member of Boolean
       b |+| c

Ouch. Why ? Well, because |+| can be interpreted in conjunction or disjunction (note that, actually this works in Scalaz 6, not sure if scalaz seven will make it work as in scalaz 6). To fix this, let's do the following:

scala> val a = Conjunction(true)
a: scalaz.package.@@[Boolean,scalaz.Tags.Conjunction] = true

scala> val b = Conjunction(true)
b: scalaz.package.@@[Boolean,scalaz.Tags.Conjunction] = true

scala> val c = Conjunction(false)
c: scalaz.package.@@[Boolean,scalaz.Tags.Conjunction] = false

scala> a |+| b
res34: scalaz.package.@@[Boolean,scalaz.Tags.Conjunction] = true

scala> a |+| c
res35: scalaz.package.@@[Boolean,scalaz.Tags.Conjunction] = false

scala> a |+| b |+| c
res36: scalaz.package.@@[Boolean,scalaz.Tags.Conjunction] = false

All right. That makes sense. What about Disjunction ? Well, just do the same.

scala> val e = Disjunction(true)
e: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = true

scala> val f = Disjunction(true)
f: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = true

scala> val g = Disjunction(false)
g: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = false

scala> val h = Disjunction(false)
h: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = false

scala> e |+| f
res37: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = true

scala> e |+| h
res38: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = true

scala> g |+| h
res39: scalaz.package.@@[Boolean,scalaz.Tags.Disjunction] = false

OK. That's cool, but it starts to be boring. Doesn't it? Give me something more spectacular.  What about Tuple?  All right, what about Tuple?

scala> (6, "Hello", List(4, 2)) |+| (7, "Hello", List(5))
res40: (Int, java.lang.String, List[Int]) = (13,HelloHello,List(4, 2, 5))

So, |+| actually "sums" each corresponding element of two tuples. That's quite cool. What if they are nested? Will it work ?

scala> (some(6), some("Hello"), (some(5), some(3))) |+| 
        (some(7), none[String], (some(6), none[Int]))

res43: (Option[Int], Option[java.lang.String], (Option[Int], Option[Int])) = 

(Some(13),Some(Hello),(Some(11), Some(3)))

Fantastic! Pretty cool.

[ I heard somebody there "you see, this Scalaz guy loves using funny operator. This time, they use |+|. OMG, That's not readable". All right, all right. You can actually change all |+| above with its alias called mappend, hope you're happier now].

Monoid and Semigroup Behind the Scene

Behind the scene, what happen is that Scalaz offers a quite simple but powerful abstraction, called Monoid. Believe me, Monoid is something quite simple: it's a type class with two functions: append and zero: 

2      trait Monoid[A] { 
3        val zero: A 
4        def append(s1 : A, s2 : => A):A
5      } 

With the following contract (or a law, if you wish)

zero append x = x
x append zero = x
(x append y) append z = x append (y append z)

Scalaz provides several instances of Monoid (we have seen some of them in action above):

  • Int, Short, BigInt, BigDecimal, Byte, Short ...
  • Boolean conjunction and disjunction
  • List and Stream
  • String
  • Either.LeftProjection and Either.RightProjection.
  • ...
What about Option and Tuple ? Actually, Scalaz also provides some derived Monoid, like:
  • Option[A] is a monoid if A is monoid 
  • Tuple[A, B, C, D] is a monoid if A, B, C, and D is monoid
  • Map [A,B] is a monoid if B is a monoid
  • ...
Map is an interesting example. Let's try this:

scala> val m = Map("UO" -> BigDecimal(40.2),
     |              "US" -> BigDecimal(50.1),
     |              "YR" -> BigDecimal(10.1))
scala> val n = Map("UO" -> BigDecimal(10.2),
     |              "US" -> BigDecimal(40.0),
     |              "YZ" -> BigDecimal(10.5))
scala> m |+| n
res47: scala.collection.immutable.Map[java.lang.String,scala.math.BigDecimal] = Map(UO -> 50.4, US -
> 90.1, YZ -> 10.5, YR -> 10.1)

As you can see, |+| adds every corresponding element in m and n. If there's no corresponding element, for example "YR" in m and "YZ" in n, then it just puts the element in the result map.

All examples so far use append function of Monoid, but not zero. A type class with only append is called Semigroup. The function zero is useful when we want to fold a list of monoid, for example using suml function also provided by scalaz:

scala> val xs = List(some(2,4), some(1, 3), some(2, 10))
xs: List[Option[(Int, Int)]] = List(Some((2,4)), Some((1,3)), Some((2,10)))

scala> xs.suml
res48: Option[(Int, Int)] = Some((5,17))

Scalaz provides a cool thing called Semigroup and Monoid. With that, we can benefit the operator |+| and sum for their instances like Integer, String, List, and so on. But the main benefit is that Scalaz provides implementation of Monoid for Option, Tuple, and Map. You don't need to know what Monoid or Semigroup are to benefit all this. But, why should you avoid them ? It's a very simple stuff.

I hope you enjoy this very express introduction to Scalaz Seven Monoid. Who said Scalaz is complex ?
 I'm preparing more on this subject. So, stay tuned.


Vidhya said...

Nice to see your blog post.. I really enjoyed by reading your blog post. Thanks a lot for sharing this with us.. Keep on sharing like this informative post.

Salesforce Training in Chennai

deeksha said...

this blog is really amazing and it is really very interesting and tremendous thanks for sharing those valuable information.

php Training in Chennai

Abiya Carol said...

It's interesting that many of the bloggers to helped clarify a few things for me as well as giving.Most of ideas can be nice content.The people to give them a good shake to get your point and across the command .

Branding Services in Chennai

Varsha aravind said...

What an awesome post, I just read it from start to end. Learned something new after a long time.

Car Cleaning Services in Mumbai

back to original car services

Shalini said...

It's interesting that many of the bloggers to helped clarify a few things for me as well as giving.Most of ideas can be nice content.The people to give them a good shake to get your point and across the command .

digital marketing company in india

vigneswaran said...

What's a fantastic programming coding I've to using this loop function for my android developed application it's very helpful to finished my Projects.
Hadoop Training in Chennai
Hadoop Training Institute in Chennai with Placement
Best Android Training in Chennai
Selenium Training in Chennai

Philips Huges said...

Its very useful to me. Wonderful blog.. Thanks for sharing informative Post.

Installment loans
Payday loans
Title loans

vinothika said...

The blog is conveys a useful information to viewere. This attached was nice.

Selenium Training in Chennai

Abitha Chetna said...

The blog gave me idea about components of hadoop.They explained in effective manner.Thanks for sharing it. Keep sharing more blogs.

Bigdata Training in Chennai

Atom Steels said...

The Interior Designer is a plans, researches, coordinates, and manages the projects. Interior design is a multifaceted profession that includes conceptual development, space planning, site inspections, programming, research, communicating with the stakeholders of a project, construction management, and execution of the design.

Interior Designers in OMR

Kalai chellam said...

Thanks for the informative article. This is one of the best resources I have found in quite some time. Nicely written and great info. I really cannot thank you enough for sharing.

Restaurant in OMR
Apartments in OMR
Villas in OMR
Resorts in OMR

sellappan ammasai said...

Testers can build, enhance, and maintain scripts to regression test their mobile applications. Hands-on instruction is provided for those who want to explore the power of using Appium. The course covers content from installation to execution and reporting . The focus is on the practical application of Appium to resolve common mobile automated testing challenges. This course focuses on getting started with Appium.

Mouni yoga said...

Thank you for allowing me to read it, welcome to the next in a recent article. And thanks for sharing the nice article, keep posting or updating news article.
python training Course in chennai
python training in Bangalore
Python training institute in bangalore

Afiah B said...

Really very nice blog information for this one and more technical skills are improve,i like that kind of post.
Java training in Bangalore | Java training in Indira nagar

Java training in Bangalore | Java training in Rajaji nagar

Java training in Bangalore | Java training in Marathahalli

Java training in Bangalore | Java training in Btm layout

Unknown said...

Good Post! Thank you so much for sharing this pretty post, it was so good to read and useful to improve my knowledge as updated one, keep blogging.
rpa training in Chennai
rpa training in bangalore
best rpa training in bangalore
rpa course in bangalore
rpa training institute in bangalore
rpa training in bangalore
rpa online training

gowsalya said...

The knowledge of technology you have been sharing thorough this post is very much helpful to develop new idea. here by i also want to share this.
Devops Training courses
Devops Training in Bangalore
Best Devops Training in pune
Devops interview questions and answers

ram said...

This is a terrific article, and that I would really like additional info if you have got any. I’m fascinated with this subject and your post has been one among the simplest I actually have read.
Data Science training in rajaji nagar | Data Science Training in Bangalore
Data Science with Python training in chennai
Data Science training in electronic city
Data Science training in USA
Data science training in pune

cathryn said...

This is good site and nice point of view.I learnt lots of useful information.

angularjs-Training in pune

angularjs Training in bangalore

angularjs Training in bangalore

angularjs Training in chennai

automation anywhere online Training

angularjs interview questions and answers