Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to choose multiplication monoid instead of addition monoid?

Tags:

scala

scalaz

I want to merge two lists:

import scalaz.syntax.align._
import scalaz.std.list._
import scalaz.std.anyVal._

List(1, 2, 3).merge(List(4, 5, 6, 7)) // Evaluates to List(5, 7, 9, 7)

This uses the standard addition monoid implicitly. What if I want use the multiplication monoid instead? What it is the idiomatic way to do this in Scalaz?

like image 983
ZhekaKozlov Avatar asked Oct 22 '14 08:10

ZhekaKozlov


People also ask

Is multiplication a monoid?

It's not a data type in itself, but rather a function (or method) that operates on that data type. For example, addition and multiplication are two different monoids that both work on numbers.

What is the difference between semigroups and monoids?

A semigroup may have one or more left identities but no right identity, and vice versa. A two-sided identity (or just identity) is an element that is both a left and right identity. Semigroups with a two-sided identity are called monoids.

Is the set of integers a monoid under multiplication?

The positive integers under multiplication form a commutative monoid, with one as identity element.

Which is not monoid with respect to addition?

The set of all positive integers (excluding zero) with addition is a semigroup, but not a monoid. 3. Since both ordinary addition and ordinary multiplication are associative, it can be deduced that addition and multiplication modulo n are also associative.


1 Answers

You can use the Multiplication tag to indicate that you want to use the multiplication monoid:

import scalaz.Tags.Multiplication

val xs = List(1, 2, 3).map(Multiplication(_))
val ys = List(4, 5, 6, 7).map(Multiplication(_))

And then:

scala> xs merge ys
res0: List[scalaz.@@[Int,scalaz.Tags.Multiplication]] = List(4, 10, 18, 7)

Multiplication.unwrap removes the tag.

You could also explicitly pass in your own instance:

scala> List(1, 2, 3).merge(List(4, 5, 6, 7))(Monoid.instance(_ * _, 1))
res1: List[Int] = List(4, 10, 18, 7)

Using tags is more idiomatic, though.

like image 165
Travis Brown Avatar answered Oct 27 '22 01:10

Travis Brown