æ¯è¼ã¯ã¢ãã¤ã
æ¯è¼ã¢ããã«ã¤ãã¦èå¯ããã¦ããä¸é£ã®ã¨ã³ããªã«æéãåãã¦ãç§ãæ¯è¼ã«ã¤ãã¦èãã¦ã¿ã¾ããã
ã¾ããèå¯å¯¾è±¡ã¨ãã¦ãæ¯è¼çµæãã¨ãæ¯è¼æä½ãã«åãã¦èãã¾ããæ¯è¼çµæã¨ããã®ã¯ãæ¯è¼å¾ã«è¿ã£ã¦ããå¤(ä¾ï¼Java ã® Comparator ã® compare ã«ããã è² ã»é¶ã»æ£)ãè¨ãã¾ããæ¯è¼æä½ã¨ããã®ã¯ãæ¯è¼ããé¢æ°(ãããã¯é¢æ°ãªãã¸ã§ã¯ã)èªä½(ä¾ï¼Java ã® Compartor
æ¯è¼çµæã¢ãã¤ã
æ¯è¼çµæã¨ããã®ã¯ã2ã¤ã®æ¯è¼å¯¾è±¡ã«å¯¾ãã¦ããã®çæ¹ãä»æ¹ããããå°ããã®ãããçããã®ããã大ããã®ããã示ãå¤ã§ããä¾ãã°ãPerl ã® æ¯è¼æ¼ç®å <=> ã Java ã® Comparator ã«ããã¦ã左辺ãå°ãããã¨ãè² ã®æ´æ°ã§ã左辺ã¨å³è¾ºãçãããã¨ã 0 ã§ã左辺ã®ã»ãã大ãããã¨ãæ£ã®æ´æ°ã§ç¤ºãã¨ãã®ãè² ã®æ´æ°ãã0ããæ£ã®æ´æ°ãã®ãã¨ãæãã¾ãã
æ¯è¼çµæãã¢ãã¤ãã¨ãã¦æ±ã£ã¦ããè¨èªã§ã¯ãæ´åãªã©ã®æä½ãé©ãã»ã©ã¹ãã¼ãã«è¨è¿°ã§ãã¾ãã
ä¾é¡ã¨ãã¦ãããã°ã®ã¨ã³ããªãæ´åããåé¡ãèãã¦ã¿ã¾ããããæ¥ä»ã®éé ã§ä¸¦ã¹ãããæ¥ä»ãåãå ´åã¯ã¨ã³ããªæ¯ã®IDã®æé ã§ä¸¦ã¹ãã¨ããåé¡ã§ãããªããããã°ã®ã¨ã³ããªã示ãã¯ã©ã¹ã®ãã£ã¼ã«ãã«ã¯ããã®ã¨ã³ããªãæ¸ãããæ¥ä»(pubDate)ã¨ãä¸æã®æ´æ°åèå¥å(id)ããããã®ã¨ãã¾ãã
ããã Java ã§æ¸ãã¨ããããªæãã§ãã¤ãã¤ã¨ãã¦ãã¾ãã¾ããã
List<Entry> entries = ...// Entry ãè¤æ°è©°ã¾ã£ã¦ãã Collections.sort(entries, new Comparator<Entry>() { public int compare(Entry e1, Entry e2) { if (!e1.pubDate.equals(e2.pubDate)) { return e2.pubDate.compareTo(e1.pubDate); } else { return new Integer(e1.id).compareTo(e2.id); } } });
ä¸è¨ã«ç¤ºãããã« groovy ã Rubyã ã¨äºæ
ã¯å°ãæ¹åããã¾ãããç¸å¤ãããæ¡ä»¶åå²ããã£ã¦ãããããã£ããããããã¯ãããæå·§çã§ãã£ããã¨ããæããããªãããªãã§ãã
ï¼ã¾ããæå·§çã¨ãã¦ç¤ºããå´ã®ã³ã¼ãã¯æ¯è¼æ¼ç®åã{-1, 0, +1}ãè¿ãã¦ããããåã«{è² , é¶, æ£}ãè¿ããããªããããªãè¡åã®æªãæ¯è¼å¯¾è±¡ã«ã¯ä½¿ãã¾ãããã¨ããããRuby ã®å ´åã¯ã-1, 0, +1 ãè¿ããã¨ãæ¨å¥¨ããã¦ããã ãã§ã-1, 0, +1 ã§ããä¿è¨¼ã¯ãªãã§ããã¤ã¾ãã-1 ã +1 ã§ã¯ãªãã¦ãåãªãè² ã®æ°ãåãªãæ£ã®æ°ãè¿ã£ã¦ãã¦ããè¿ãå´ã¯ãæ£å¸¸åä½ããªã®ã§ãæå·§çãªã»ãã®ã³ã¼ããåãä¿è¨¼ã¯ãªãã§ããï¼
#-- æ®éã«æ¸ãã¦ã¿ãã³ã¼ã entries.sort { |e1, e2| if e1.pubDate != e2.pubDate e2.pubDate <=> e1.pubDate else e1.id <=> e2.id end } #-- ããæå·§çãªã³ã¼ããï¼<=>ãè¿ãå¤ã®ç¯å²ã¯{è² , é¶, æ£} ã§ã¯ãªã å¿ ã{-1, 0, +1}ãè¿ãã¦ããããã¨ãæå¾ ï¼ entries.sort { |e1, e2| 2 * (e2.pubDate <=> e1.pubDate) + (e1.id <=> e2.id) }
éã«æ´å²çã«å¤ã perl ã®ã»ããããããæ¬è³ªãè¦äºã«è¡¨ç¾ã§ãã¾ããpubDate ã§æ¯è¼ãã¦ããã§ã決ã¾ããªããã° id ã§æ¯è¼ããã¨ããæ¬è³ªãã
sort { my ($e1, $e2) = @_; ($e2->{pubDate} <=> $e1->{pubDate}) || ($e1->{id} <=> $e2->{id}) } @entries;
è¿½è¨ 2011-06-20
å½åãä¸è¨ã® Rubyã³ã¼ã ã¯Groovyã³ã¼ãã§ãããã¾ãããGroovyãRubyã§ã¯ãã¨è¨ãã¦ãã¾ãããããã®é¨åãä¿®æ£ãã¾ãããã³ã¡ã³ãæ¬ã§ id:deve68 ããããææã®éãã?: æ¼ç®åã使ãã°ã¹ãã¼ãã«è§£æ±ºã§ãã¾ãã
entries.sort { e1, e2 -> (e2.pubDate <=> e1.pubDate) ?: (e1.id <=> e2.id) }
(追è¨ããã¾ã§ãä»ã®è¿½è¨ã»åé¤ç®æã¯>ins<ã«ããä¸ç·ã>del<ã«ããææ¶ç·ã§ç¤ºãã¾ãã)
ã§ãPerl ãGroovyã ã¨ä¸æãæ¸ããçç±ãçªãè©°ããã¨ãæ¯è¼æ¼ç®å <=> ã®çµæãã¢ãã¤ãã ããã ã¨æãã¾ãããæ´æ°ãæ¯è¼çµæã¨ã¿ãªããã¨ãã|| ãå群ã®äºé æ¼ç®ã«ãªã£ã¦ãã¦ã0ãåä½å ãªã®ã§ããã£ï¼
ããå°ã説æã試ã¿ãã¨ãã¢ãã¤ãã¨ããã®ã¯ãåä½å ãæã¤å群ã®ãã¨ã§ãã
å群ã¨ããã®ã¯ã2ã¤ã®è¦ç´ (ã¤ã¾ããããã§ã¯æ¯è¼çµæ)ã2é æ¼ç®ã§ãã£ã¤ã1ã¤ã®è¦ç´ ã«ã§ãã2é æ¼ç®(ããã§ã¯ ||)ãå®ç¾©ããã¦ããéå(ããã§ã¯æ¯è¼çµæã§ãããè² ã®æ´æ°ãã0ããæ£ã®æ´æ°ã)ã§ããã¾ãããã®å群ã«ãããåä½å ã¨ã¯ãç¸æã®è¦ç´ ã¨2é æ¼ç®ã§ãã£ã¤ãã¦ããç¸æã®è¦ç´ ãå¤åããªãè¦ç´ ã®ãã¨ã§ããããã§ã¯ã0ã®ãã¨ã§ãã
Perl ã® || ã¨ããæ¼ç®åã®æåã£ã¦ãç¾ä»£ç観ç¹ããã¿ã¦ãé©ãã»ã©ãã¡ãã¨èãããã¦ãã¦ãåã«OR(è«çå) ã¨ããã ãã§ãªããããããåãã®åä½ãä¸è¬åãããã®ã«ãªã£ã¦ãã¾ããä¾ãã°ãscala ã«ããã Option ã¢ããã® orElse åä½ã«ç¸å½ããåä½ããPerl ã® || ã«ã¯å«ã¾ãã¦ãã¾ãã (null || value)ã¨æ¸ãã°ãã¡ãã㨠value ãè¿ã£ã¦ãã¾ãããã¡ãªã¿ã«ããã® orElse ã£ã¦ã仮㫠Maybe/Optionã¢ãã ã® MonadPlusçãªããã®ãããã¨ããã°ã確å®ã« plus === orElse ã¨å®ç¾©ããã®ãçã«ããªã£ã¦ããããã Plus ãªãã§ããã
ã§ãscala ã®è©±ã«ãªãã¾ãããscalaæ¨æºã£ã¦ãé©ãã»ã©ã¤ã±ãã¤ããªããscala.math.Ordering#compare ã«ãã£ã¦è¿ãããæ¯è¼çµæã®ä½ãã¤ã±ã¦ããªããã¨è¨ãã°ãããããããé©ãã»ã© Java ãªãã§ããããããè¿ãå®ä½ã¯ Java ã Perl ã Groovy ããã¯ãã¾ããC ã® strcmp ã§ãããåãã§ãæ´æ°ã®è² ã»é¶ã»æ£ãªãã§ããããã®è¿ã£ã¦ããå¤ãã©ãè¦åãã®ãããã¡ãã¡ã§ãã¦ãscala æ¨æºã¯ãPerlã«å ¨ç¶åã°ãªããå°ãªãã¨ãç§ã® scala å®åã«ããã¦ã¯ãscala ã§ã®ã¹ãã¼ããªã³ã¼ãã¯æãæµ®ãã°ãªãã§ããsorted ã® implicit ãªå¼æ°ã« Ordering ãæ示çã«æ¸¡ãã®ãã¹ãã¼ãã§ã¯ãªããsortWith 㯠less ãå¦ãã Boolean ã§è¿ãã ããªã®ã§(minimalism ã®ç¹ã§ã¯ãç§ã¯å¥½ãã ããã©)ãOrdering ã Comparator ã®ç¸æ§ãå¾®å¦ã§ãããããªããããã scala ã®æ´åã®æ¥é¨ã¨ããæããããªãããªãã®ã§ããªãããããããã³ã¼ããè¼ããæ°ããã¾ããã(æ®æ®µã¯ãããããã³ã¼ããæ¸ãã¦ãã¾ãããã©ãã)
ããã§ã試ãã«ãããã¦ãæ®æ®µã¯çµ¶å¯¾ã«æ¸ããªããããªæ¸ãæ¹ããã¦ã¿ã¾ãã
// æ£å¸¸åä½ããããã©ãæ¸ãæã®æå³ãåããã«ããã¦ã³ã³ã¼ã entries.sortBy { e => e.pubDate -> (-1-e.id) }.reverse
ãã¡ããããã®ã³ã¼ãããã¡ãä½ããã¡ãã¨ããã¨ãä¸è¦ããã ãã§ã¯ä½ãããããä¸æã ããæ¡å¼µæ§ã«ä¹ããããã§ãããã¾ããè¬ãããã®ã³ã¼ãçãè¦ã¦æå³ãä¸ç®çç¶ã§æ¡å¼µã®ä»æ¹ãæ³å®ã§ãã人ã°ããã®ä¸çã§ãã£ãã¨ãã¦ããæ¯è¼æ¯ã« Tuple2 ãçæãããreverseãããã§ããã©ã¼ãã³ã¹ãæªãã§ãã
ããã§ãæºãæãã¦ç»å ´ããã®ã ScalaZã©ã¤ãã©ãªã§ãã
ScalaZ ã®ä½ãããããã£ã¦ããã¨ããæ¯è¼çµæã¯ã¢ãã¤ãã ãã£ã¦æ示çã«è¨æãã¡ãã£ã¦ãã®ã§ãããæ£ç¢ºã«ã¯ãã¾ããæ¯è¼å¯è½ãªãã®ã«å¯¾ãã¦ã¯ Order ã¨ããåã¯ã©ã¹ãå®ç¾©ããç´æã«ãªã£ã¦ãããã§ãããã§ãOrder ã®ã¤ã³ã¹ã¿ã³ã¹ã¡ã½ãã order ã«ããæ¯è¼çµæã«å°ç¨ã®ä»£æ°çãã¼ã¿å(scalaz.Ordering = LT | EQ | GT)ãä½ã£ã¦ãããã§ããããã¼ãåå®å ¨ã§ãããããã«ãããã¤ã«å¯¾ããåã¯ã©ã¹ Semigroup 㨠Zero ãåãã£ã¦ããï¼ããªãã¡ãscalaz.Ordering ãåä½çå群â¡ã¢ãã¤ãã§ããï¼ã®ã§ããã
ã¤ã¾ãããããªãã¨ããã§ãããã§ãã
entries.sorted(OrderOrdering(order{ (e1: Entry, e2: Entry) => (e2.pubDate ?|? e1.pubDate) |+| (e1.id ?|? e2.id) }))
è¦ç¹ã¯ããã§ãï¼
(e2.pubDate ?|? e1.pubDate) |+| (e1.id ?|? e2.id)
?|? ã¯ãæ¯è¼æ¼ç®åãOrderåã¯ã©ã¹ãåãã£ã¦ããä»»æã®åã®ã¤ã³ã¹ã¿ã³ã¹å士ãæ¯è¼ããæ¼ç®åã¡ã½ãããæ¯è¼çµæã¯ãscalaz.Ordering (scala.math.Orderig[T] ã¨ã¯å¥ç©)ãã§ããã® scalaz.Ordering ã¯ã¢ãã¤ãã§ããããã£ã¤ããæ¼ç®ã |+| ãªãã§ããEQãåä½å ãªã®ã§ãããã¨ã念é ã«ããã°ããçæ¹ã EQ ã§ããã°ãä»æ¹ã®çµæãè¿ãï¼ã©ã¡ããEQã§ãªããªãã°ãå·¦å´ï¼ããªãã¡åªå å´ï¼ãè¿ããã¨ãããã¨ã¯ãã»ã¨ãã©èªæãã¤èªç¶ã
ããããPerl ã¨éã£ã¦ãscala/scalazã¯åå®å ¨ãªãã§ãï¼ï¼ï¼ï¼
æ¯è¼æä½ã¢ãã¤ã
ã§ãããã¾ã§ã¯ãæ¯è¼çµæ(= LT, EQ, GT ã¨ã -1, 0, +1 ã¨ã)ãã¢ãã¤ãã¨è¦åãã¨ã¦ã¬ã·ã¤ï¼ããå®é scalaz ã§ã¯ ã¢ãã¤ãï¼ã¨ãããã¨ã«ã¤ãã¦ã§ããã
次ã«ãæ¯è¼æä½(= Comparator ã¨ã <=> ã¨ã)ã¯ãä½ãªã®ï¼ã©ã®ããã«è¦åãã°ä¸çãã·ã³ãã«ã«è¦ããã®ããã¾ãåãã®ï¼ã£ã¦ãã話ã§ãã
ã¾ãã¯ããããå°ã¨ãã¦ãã¨ããããã¢ãã¤ãã«ãã¦ã¿ã¾ããã
æ¯è¼æä½ã®å群ã®ããã®2é æ¼ç®ã¯ãå°æ¥çã« apply ãããã¨ã(= æ¯è¼æä½ãè¡ãããã¨ãã«)ã左辺ã EQ ãè¿ããªãã°å³è¾ºã«å¤æãå§è²ãã左辺ãGT/LTãè¿ããªãã°ãã®çµæãè¿ãããããªæ¯è¼æä½ãè¿ããããã§ãåä½å 㯠EQãã¨ãããããªæãã§ãã
// Order(scalaz ã®æ¯è¼å¨)ãã¢ãã¤ãã«ããããã®åã¯ã©ã¹ trait OrderAsMonoid { // å群ãä¸ãã implicit def OrderSemigroup[T]: Semigroup[Order[T]] = semigroup { (o1, o2) => order{ (x, y) => o1.order(x, y) |+| o2.order(x, y) } } // åä½å ãä¸ãã implicit def OrderZero[T]: Zero[Order[T]] = zero(order{(x, y) => EQ}) }
ä¸è¨ã®ããã« Order ã«å¯¾ããã¢ãã¤ãåã¯ã©ã¹ãå®ç¾©ããã¨ãä¸è¨ã®ãããªæãã®ãã¨ãã§ãã¾ãã
import scalaz._ import scalaz.Scalaz._ import java.util.Date object OrderMonoidTest extends App with OrderAsMonoid with OrderLow { // Entry ã pubDate ã®éé ã§ä¸¦ã¹ã Order val orderEntryByPubDateDesc: Order[Entry] = order {(e1, e2) => e2.pubDate ?|? e1.pubDate} // Entry ã id ã®æé ã§ä¸¦ã¹ã Order val orderEntryByIdAsc: Order[Entry] = orderBy {_.id} // OrderAsMonoid ã«ãããä»ã Order èªä½ãã¢ãã¤ããªã®ã§ãOrder èªä½ã |+| ã«ããçµåå¯è½ val orderEntryByPubDateDescOrElseByIdDesc = orderEntryByPubDateDesc |+| orderEntryByIdAsc // scala ã® sorted ãå¼ã³åºãããã«ãscalaz.Order ã scala.math.Ordering ã«å¤æ val theOrderAsScalaOrdering = Order.OrderOrdering(orderEntryByPubDateDescOrElseByIdDesc) val sortedEntries = EntryManager.entries.sorted(theOrderAsScalaOrdering) }
æ¯è¼çµæãã¢ãã¤ãã¨ã¿ãæãã¨ããã®ã¯ãèªåã®ä¸ã§ã¯ããªãããæããããªããã¨æã£ã¦ãã¾ããï¼ç¡è«ãã¢ãã¤ãã¨ããè¦æ¹ãããè¦æ¹ã¨ããã ãã§ãã£ã¦ãä»ã®è¦æ¹ãæªãããã§ã¯ãªãã§ãããã£ã¨ããè¦æ¹ãããããããã¾ãããããã or ãããªããã¨ããã®ã¯æã¨å ´åã«ä¾ãé¨åãããã¨æãã¾ããï¼
ã§ãæ¯è¼æä½ãã¢ãã¤ãã¨ã¿ãæãã¨ããã®ã¯ãã¾ã èªåã®ä¸ã§ããç´å¾ã§ãã¦ããªãé¨åãããã¾ããã¨ããã®ã¯ãç´ ç´ã«èãã¦ãComparator
ã¡ãã£ã¨ãæå¾ã®ã»ããã°ãã°ãã«ãªã£ã¦ãã¾ãã¾ãã^^ï¼