001 package fj; 002 003 import static fj.Unit.unit; 004 005 /** 006 * Represents a side-effect. 007 * 008 * @version %build.number%<br> 009 * <ul> 010 * <li>$LastChangedRevision: 122 $</li> 011 * <li>$LastChangedDate: 2009-04-25 08:24:38 +1000 (Sat, 25 Apr 2009) $</li> 012 * </ul> 013 */ 014 public interface Effect<A> { 015 void e(A a); 016 017 /** 018 * A projection of an effect. The methods defined on a projection may belong on an effect, 019 * however, this would disallow the use of {@link Effect} to be used with Java 7 closure syntax. 020 */ 021 @SuppressWarnings({"InnerClassOfInterface"}) 022 final class Projection { 023 private Projection() { 024 throw new UnsupportedOperationException(); 025 } 026 027 /** 028 * Returns an effect for the given function. 029 * 030 * @param f The function to produce the effort with. 031 * @return The effect using the given function. 032 */ 033 public static <A> Effect<A> f(final F<A, Unit> f) { 034 return new Effect<A>() { 035 public void e(final A a) { 036 f.f(a); 037 } 038 }; 039 } 040 041 /** 042 * Returns a function for the given effect. 043 * 044 * @param e The effect to produce the function with. 045 * @return The function using the given effect. 046 */ 047 public static <A> F<A, Unit> e(final Effect<A> e) { 048 return new F<A, Unit>() { 049 public Unit f(final A a) { 050 e.e(a); 051 return unit(); 052 } 053 }; 054 } 055 056 /** 057 * A contra-variant functor on effect. 058 * 059 * @param e The effect to map over. 060 * @param f The function to map over the effect. 061 * @return An effect after a contra-variant map. 062 */ 063 public static <A, B> Effect<B> comap(final Effect<A> e, final F<B, A> f) { 064 return new Effect<B>() { 065 public void e(final B b) { 066 e.e(f.f(b)); 067 } 068 }; 069 } 070 } 071 }