ã¢ããã®ãã¨æ¤ç´¢ãã¦ãã次ã®ãããªtweetè¦ãããã
å¦çã®æµããå¶å¾¡ãããã¨ãç®çãªã確ãã«Option(Maybeã¢ãã)ã§ååã ã£ããããããªãã
前回ã®ãã¤ãæ¸ãç´ãã¦ã¿ãã
Optionã®å®è£
Javaã§ããã¨ãããªæãã ãã*1
orElseã¯å¤åmplusã«ãªãã®ã§mplusã£ã¦ã¡ã½ããåã«ãã¦ã¾ãã
package sample.maybe; import java.util.NoSuchElementException; import org.apache.commons.lang.Validate; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import com.google.common.base.Function; @SuppressWarnings({"unchecked", "rawtypes"}) public final class Options { public interface Option<T> { public T get(); public boolean isEmpty(); public <S> Option<S> bind(Function<T, Option<S>> func); public Option<T> mplus(Option<T> other); } public static <T> Option<T> someOf(T value) { return new Some(value); } private static Option NONE = new None(); public static <T> Option<T> none() { return (Option<T>)NONE; } public static <T> Option<T> unit(T element) { return someOf(element); } public static <T> Option<T> mzero() { return none(); } public static abstract class AbstractOption<T> implements Option<T> { public final boolean equals(Object other) { return EqualsBuilder.reflectionEquals(this, other); } public final int hashCode() { return HashCodeBuilder.reflectionHashCode(this); } public String toString() { return ToStringBuilder.reflectionToString(this); } } final static class Some<T> extends AbstractOption<T> { private final T value; Some(T value) { Validate.notNull(value); this.value = value; } @Override public T get() { return value; } @Override public boolean isEmpty() { return false; } @Override public <S> Option<S> bind(Function<T, Option<S>> func) { return func.apply(get()); } @Override public Option<T> mplus(Option<T> other) { return this; } } final static class None<T> extends AbstractOption<T> { None() { } @Override public T get() { throw new NoSuchElementException(); } @Override public boolean isEmpty() { return true; } @Override public <S> Option<S> bind(Function<T, Option<S>> func) { return (Option<S>) this; } @Override public Option<T> mplus(Option<T> other) { return other; } } }
Some#mplus(Option other)ã®çµæã¯this, None#mplus(Option other)ã®çµæã¯otherã«ãªãããã«ãã¦ããã
OptionçComparator
intåã®ç¬¦å·ã§ã¯ãªãOptionãæ»ãComparatorãå®ç¾©ããã
public interface ComparatorO<T> { /** * left,rightã®æ¯è¼ãè¡ããå·¦å´ãå°ããå ´åOptions.someOf(è² ã®æ°)ã * å·¦å´ã大ããå ´åOptions.someOf(æ£ã®æ°)ãçããå ´åOptions.someOf(0)ã * ä¸å®ã®å ´åã«Options.none()ã®çµæãæ»ãã * @return Optionã§çµæãæ»ãã */ Option<Integer> compare(T left, T right); }
使ç¨ä¾
ååã®WeblogEntriesComparatorãComparatorOã使ã£ã¦å®è£ ãã¦ã¿ãã
// (1)pubDateã®éé ã(2)idã®æé ãã¨ããé åºã§ã½ã¼ãããæã®Comparator public class WeblogEntriesComparator implements Comparator<WeblogEntries> { // pudDate ã§æ¯è¼ããComparatorO private ComparatorO<WeblogEntries> pubDateComparator = new ComparatorO<WeblogEntries>() { public Option<Integer> compare(WeblogEntries left, WeblogEntries right) { int sign = left.getPubDate().compareTo(right.getPubDate()); return sign != 0 ? Options.someOf(-1 * sign) : Options.<Integer>none(); } }; // id ã§æ¯è¼ããComparatorO private ComparatorO<WeblogEntries> idComparator = new ComparatorO<WeblogEntries>() { public Option<Integer> compare(WeblogEntries left, WeblogEntries right) { int sign = left.getId().compareTo(right.getId()); return sign != 0 ? Options.someOf(sign) : Options.<Integer>none(); } }; @Override public int compare(WeblogEntries entry1, WeblogEntries entry2) { return pubDateComparator.compare(entry1, entry2) .mplus(idComparator.compare(entry1, entry2)) .mplus(Options.someOf(0)).get(); } }
ãç°¡åã«ã½ã¼ãé ãå
¥ãæ¿ããã追å ãããããããã¨ããç®çã«ã¯ãã¾ãããã§ååãªæ°ãããã
å¼æ°ãEagerã«è©ä¾¡ããã¦ãã¾ãã®ã§å¦ççã«ç¡é§ãåºã¦ãã¾ããã©ã