设为首页 加入收藏

TOP

Scalaz(8)- typeclass:Monoid and Foldable(一)
2017-10-10 12:13:43 】 浏览:11558
Tags:Scalaz typeclass Monoid and Foldable

  Monoid是种最简单的typeclass类型。我们先看看scalaz的Monoid typeclass定义:scalaz/Monoid.scala

1 trait Monoid[F] extends Semigroup[F] { self =>
2   ////
3   /** The identity element for `append`. */
4  def zero: F 5 ...

Monoid trait又继承了Semigroup:scalaz/Semigroup.scala

 1 trait Semigroup[F]  { self =>
 2   ////
 3   /**  4  * The binary operation to combine `f1` and `f2`.  5  *  6  * Implementations should not eva luate the by-name parameter `f2` if result  7  * can be determined by `f1`.  8    */
 9   def append(f1: F, f2: => F): F 10 ...

所以获取一个类型的Monoid实例需要实现zero和append这两个抽象函数。实际上Monoid typeclass也就是支持了append(|+|)这么一个简单的操作。scalaz为一些标准类型定义了Monoid实例:

1 0 |+| 30                                         //> res0: Int = 50
2 20.some |+| 30.some                               //> res1: Option[Int] = Some(50)
3 List(1,2,3) |+| List(4,5,6)                       //> res2: List[Int] = List(1, 2, 3, 4, 5, 6)
4 Tags.Multiplication(3) |+| Monoid[Int @@ Tags.Multiplication].zero 5                                                   //> res3: scalaz.@@[Int,scalaz.Tags.Multiplication] = 3
6 Tags.Conjunction(true) |+| Tags.Conjunction(false)//> res4: scalaz.@@[Boolean,scalaz.Tags.Conjunction] = false
7 Tags.Disjunction(true) |+| Tags.Disjunction(false)//> res5: scalaz.@@[Boolean,scalaz.Tags.Disjunction] = true
8 Monoid[Boolean @@ Tags.Conjunction].zero          //> res6: scalaz.@@[Boolean,scalaz.Tags.Conjunction] = true
9 Monoid[Boolean @@ Tags.Disjunction].zero          //> res7: scalaz.@@[Boolean,scalaz.Tags.Disjunction] = false

就这么来看好像没什么值得提的。不过Ordering的Monoid倒是值得研究一下。我们先看看Ordering trait:scalaz/Ordering.scala

 1  implicit val orderingInstance: Enum[Ordering] with Show[Ordering] with Monoid[Ordering] = new Enum[Ordering] with Show[Ordering] with Monoid[Ordering] {  2     def order(a1: Ordering, a2: Ordering): Ordering = (a1, a2) match {  3       case (LT, LT)      => EQ  4       case (LT, EQ | GT) => LT  5       case (EQ, LT)      => GT  6       case (EQ, EQ)      => EQ  7       case (EQ, GT)      => LT  8       case (GT, LT | EQ) => GT  9       case (GT, GT)      => EQ 10  } 11 
12     override def shows(f: Ordering) = f.name 13 
14     def append(f1: Ordering, f2: => Ordering): Ordering = f1 match { 15       case Ordering.EQ => f2 16       case o           => o 17  } 18 ...

这里定义了Ordering的Monoid实例。它的append函数意思是:两个Ordering类型值f1,f2的append操作结果:假如f1是EQ就是f2,否则是f1:

 1 (Ordering.EQ: Ordering) |+| (Ordering.GT: Ordering)  2                                                   //> res8: scalaz.Ordering = GT
 3 (Ordering.EQ: Ordering) |+| (Ordering.LT: Ordering)  4                                                   //> res9: scalaz.Ordering = LT
 5 (Ordering.GT: Ordering) |+| (Ordering.EQ: Ordering)  6                                                   //> res10: scalaz.Ordering = GT
 7 (Ordering.LT: Ordering) |+| (Ordering.EQ: Ordering)  8                                                   //> res11: scalaz.Ordering = LT
 9 (Ordering.LT: Ordering) |+| (Ordering.GT: Ordering) 10                                                   //> res12: scalaz.Ordering = LT
11 (Ordering.GT: Ordering) |+| (Ordering.LT: Ordering) 12                                                   //> res13: scalaz.Ordering = GT

如果我用以上的特性来比较两个String的长度:如果长度相等则再比较两个String的字符顺序。这个要求刚好符合了Ordering Monoid实例的append操作:

1 3 ?|? 4                                           //> res14: scalaz.Ordering = LT
2 "abc" ?|? "bac"                                   //> res15: scalaz.Ordering = LT
3 def strlenCompare(lhs: String, rhs: String): Ordering =
4  (lhs.length ?|? rhs.length) |+| (lhs ?|? rhs)    //> strlenCompare: (lhs: String, rhs: String)scalaz.Ordering
5 
6 strlenCompare("abc","aabc")                       //> res16: scalaz.Ordering = LT
7 strlenCompare("abd","abc")                        //> res17: scalaz.Ordering = GT

这个示范倒是挺新鲜的。

好了,单看Monoid操作会觉着没什么特别,好像不值得研究。实际上Monoid的主要用途是在配合可折叠数据结构(Foldable)对结构内部元素进行操作时使用的。我们再看看这个Foldable

首页 上一页 1 2 3 4 5 下一页 尾页 1/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇8.Spark集群测试 下一篇Scalaz(9)- typeclass:checki..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目