001 package fj.data.fingertrees; 002 003 import fj.pre.Monoid; 004 import fj.F; 005 006 /** 007 * Determines how the elements of a tree are measured and how measures are summed. Consists of a monoid and a 008 * measuring function. Different instances of this class will result in different behaviours for the tree. 009 */ 010 public final class Measured<V, A> { 011 private final Monoid<V> m; 012 private final F<A, V> measure; 013 014 private Measured(final Monoid<V> m, final F<A, V> measure) { 015 this.m = m; 016 this.measure = measure; 017 } 018 019 public static <V, A> Measured<V, A> measured(final Monoid<V> m, final F<A, V> measure) { 020 return new Measured<V, A>(m, measure); 021 } 022 023 /** 024 * Returns the monoid used to sum measures. 025 * 026 * @return the monoid used to sum measures. 027 */ 028 public Monoid<V> monoid() { 029 return m; 030 } 031 032 /** 033 * Returns the measuring function. 034 * 035 * @return the measuring function. 036 */ 037 public F<A, V> measure() { 038 return measure; 039 } 040 041 /** 042 * Measures a given element. 043 * 044 * @param a An element to measure. 045 * @return the element's measurement. 046 */ 047 public V measure(final A a) { 048 return measure.f(a); 049 } 050 051 /** 052 * Sums the given measurements with the monoid. 053 * 054 * @param a A measurement to add to another. 055 * @param b A measurement to add to another. 056 * @return The sum of the two measurements. 057 */ 058 public V sum(final V a, final V b) { 059 return m.sum(a, b); 060 } 061 062 /** 063 * Returns the identity measurement for the monoid. 064 * 065 * @return the identity measurement for the monoid. 066 */ 067 public V zero() { 068 return m.zero(); 069 } 070 071 /** 072 * A measured instance for nodes. 073 * 074 * @return A measured instance for nodes. 075 */ 076 public Measured<V, Node<V, A>> nodeMeasured() { 077 return new Measured<V, Node<V, A>>(m, new F<Node<V, A>, V>() { 078 public V f(final Node<V, A> node) { 079 return node.measure(); 080 } 081 }); 082 } 083 084 /** 085 * A measured instance for digits. 086 * 087 * @return A measured instance for digits. 088 */ 089 public Measured<V, Digit<V, A>> digitMeasured() { 090 return new Measured<V, Digit<V, A>>(m, new F<Digit<V, A>, V>() { 091 public V f(final Digit<V, A> d) { 092 return d.measure(); 093 } 094 }); 095 } 096 097 }