Skip to content

Instantly share code, notes, and snippets.

@sshark
Last active August 29, 2015 14:27
Show Gist options
  • Select an option

  • Save sshark/2024566dac6eac520942 to your computer and use it in GitHub Desktop.

Select an option

Save sshark/2024566dac6eac520942 to your computer and use it in GitHub Desktop.
// following http://inoio.de/blog/2014/07/19/type-class-101-semigroup/
trait Semigroup[A] {
def append(a: A, b: A): A
}
implicit val intSemigroup = new Semigroup[Int] {
def append(a: Int, b: Int) = a + b
}
object Semigroup {
def apply[A](implicit F: Semigroup[A]) = F
}
Semigroup.apply[Int].append(1, 2)
Semigroup[Int].append(1, 2)
// shorter form
trait SemigroupSyntax[A] {
def self: A
def F: Semigroup[A]
def |+|(b: A): A = append(b)
// alias for append
def append(b: A): A = F.append(self, b)
}
implicit def ToSemigroupOps[A: Semigroup](a: A): SemigroupSyntax[A] =
new SemigroupSyntax[A] {
def self: A = a
def F: Semigroup[A] = implicitly[Semigroup[A]]
}
/* or alternatively a more lengthy form without using 'implicitly', for instance,
*
* implicit def ToSemigroupOps[A](a: A)(implicit ev:Semigroup[A]): SemigroupSyntax[A] =
* new SemigroupSyntax[A] {
* def self: A = a
* def F: Semigroup[A] = ev
* }
*/
3 |+| 4 // 7
implicit def optionInstances[A: Semigroup] = new Semigroup[Option[A]] {
def append(a: Option[A], b: Option[A]): Option[A] = {
(a, b) match {
case (Some(a1), Some(b1)) => Some(Semigroup[A].append(a1, b1))
case (Some(_), None) => a
case (None, Some(_)) => b
case _ => None
}
}
}
Option(30).append(Option(40)) == (Option(30) |+| Option(40)) // true; both equals to Option(70)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment