2011年12月4日日曜日

Order, Ordering

OrderOrderingについて。

OrderはEqualを継承しており、比較を可能にします。

Scala標準のAPIにもOrdered, Orderingがありますが、これらはJavaのComparableのように正、零、負で表しています。

しかし、このOrderでは比較結果をOrderingという型で返します。

?|?

比較結果を得るもの。
compareToみたいなもの。

1 ?|? 1 assert_=== EQ
1 ?|? 2 assert_=== LT
2 ?|? 1 assert_=== GT
"Scalaz" ?|? "Scala" assert_=== GT
List(2, 4) ?|? List(3, 5) assert_=== LT
view raw order1.scala hosted with ❤ by GitHub

これらがそれぞれequal, less than, greater thanを表しています。

これが素晴らしいところはOrderingがモノイドであること。

これにより、優先順位の高い比較結果から順に結合していくことで適切な比較結果を得られます。

(1 ?|? 1) |+| (1 ?|? 1) |+| (1 ?|? 1) assert_=== EQ
(1 ?|? 1) |+| (1 ?|? 2) |+| (2 ?|? 1) assert_=== LT
(1 ?|? 1) |+| (2 ?|? 1) |+| (1 ?|? 2) assert_=== GT
view raw order5.scala hosted with ❤ by GitHub

比較結果モノイドについては、 比較はモノイド の記事が面白いので是非見て下さい。

lt, gt, lte, gte

比較する関数です。
標準のものと違うところは型安全なところと、記号じゃないから括弧で括らないといけないところ。

assert(1 lt 2)
assert(2 gt 1)
assert("Scalaz" gt "Scala")
assert(List(2, 4) lt List(3, 5))
view raw order2.scala hosted with ❤ by GitHub

max, min

2値の間で最大、最小を得る関数。

1 max 1 assert_=== 1
1 max 2 assert_=== 2
2 min 1 assert_=== 1
Identity("Scala") max "Scalaz" assert_=== "Scalaz"
Identity(List(2, 4)) min List(3, 5) assert_=== List(2, 4)
view raw order3.scala hosted with ❤ by GitHub

Orders

order, orderBy

Orderのインスタンスを作ります。
orderは2つの値を取り比較結果を返す関数を渡します。
orderByは値を取り、比較可能な値を返す関数を渡します。

case class Ikamusume(syokusyu: Int)
implicit def IkamusumeOrder: Order[Ikamusume] = order(_.syokusyu ?|? _.syokusyu)
implicit def IkamusumeOrder: Order[Ikamusume] = orderBy(_.syokusyu)
Ikamusume(10) ?|? Ikamusume(100) assert_=== LT
view raw order4.scala hosted with ❤ by GitHub

scala標準のOrderingも暗黙の型変換でOrderのインスタンスを得ることができます。

比較する際はjava.lang.Comparable, scala.math.Orderingよりもscalaz.Orderの検討を!

0 件のコメント:

コメントを投稿