今天学到第10章Monoid,在做练习10.9时有一些和作者不一样的解法,分享一下。先看题目:
使用foldMap来判定给定的IndexedSeq[Int]是否有序。需要想一个创造性的Monoid。
我们先看一下作者给出的答案吧:
// This implementation detects only ascending order, | |
// but you can write a monoid that detects both ascending and descending | |
// order if you like. | |
def ordered(ints: IndexedSeq[Int]): Boolean = { | |
// Our monoid tracks the minimum and maximum element seen so far | |
// as well as whether the elements are so far ordered. | |
val mon = new Monoid[Option[(Int, Int, Boolean)]] { | |
def op(o1: Option[(Int, Int, Boolean)], o2: Option[(Int, Int, Boolean)]) = | |
(o1, o2) match { | |
// The ranges should not overlap if the sequence is ordered. | |
case (Some((x1, y1, p)), Some((x2, y2, q))) => | |
Some((x1 min x2, y1 max y2, p && q && y1 <= x2)) | |
case (x, None) => x | |
case (None, x) => x | |
} | |
val zero = None | |
} | |
// The empty sequence is ordered, and each element by itself is ordered. | |
foldMapV(ints, mon)(i => Some((i, i, true))).map(_._3).getOrElse(true) | |
} |
val orderMonoid=new Monoid[(Int,Int,Boolean)] { def op(a1:(Int,Int,Boolean),a2:(Int,Int,Boolean))={ val b1=if(a1._1>=a2._1) true else false val b2=if(a1._2<=a2._2) true else false (a1._1.min(a2._1),a1._2.max(a2._2),a1._3&&a2._3&&(b1||b2)) } def zero=(Int.MaxValue,Int.MinValue,true) } val seq=IndexedSeq[Int](10,8,6,5,4,3) val isOrdered=foldMap(seq,orderMonoid)(x=>(x,x,true))._3