Examples 1.5

Examples (BGGA)

These examples use standard Java 1.5 syntax where an instance of the fj.F interface is passed to emulate closures.


Array exists §

Checks for the existence of a String that has all lower case characters. In this case it is true (since, the case of "what"), but without this specific case, it is false. This example uses List.forall to test the characters of the String.

import fj.F;
import fj.data.Array;
import static fj.data.Array.array;
import static fj.data.List.fromString;
import static fj.function.Characters.isLowerCase;

public final class Array_exists {
  public static void main(final String[] args) {
    final Array<String> a = array("Hello", "There", "what", "DAY", "iS", "iT");
    final boolean b = a.exists(new F<String, Boolean>() {
      public Boolean f(final String s) {
        return fromString(s).forall(isLowerCase);
      }
    });
    System.out.println(b); // true ("what" provides the only example; try removing it)
  }
}

Array filter §

Removes elements from an array that do not meet a certain criteria. In this case, we are using an array of integers and the filter removes any odd numbers.

import fj.data.Array;
import static fj.data.Array.array;
import static fj.pre.Show.arrayShow;
import static fj.pre.Show.intShow;
import static fj.function.Integers.even;

public final class Array_filter {
  public static void main(final String[] args) {
    final Array<Integer> a = array(97, 44, 67, 3, 22, 90, 1, 77, 98, 1078, 6, 64, 6, 79, 42);
    final Array<Integer> b = a.filter(even);
    arrayShow(intShow).println(b); // {44,22,90,98,1078,6,64,6,42}
  }
}

Array foldLeft §

Reduces the list applying a function per element. In this case, the fold sums the elements with a starting value of 0. Since 0 + 97 + 44 + 67 + 3 + 22 + 90 + 1 + 77 + 98 + 1078 + 6 + 64 + 6 + 79 + 42 == 1774 the result of the fold is 1774.

import fj.data.Array;
import static fj.data.Array.array;
import static fj.function.Integers.add;

public final class Array_foldLeft {
  public static void main(final String[] args) {
    final Array<Integer> a = array(97, 44, 67, 3, 22, 90, 1, 77, 98, 1078, 6, 64, 6, 79, 42);
    final int b = a.foldLeft(add, 0);
    System.out.println(b); // 1774
  }
}

Array forall §

Checks that all Strings in the array have lower case characters. In this case, the check fails because of the case of "There", however, the removal of this case produces a result of true.

import fj.F;
import fj.data.Array;
import static fj.data.Array.array;
import static fj.data.List.fromString;
import static fj.function.Characters.isLowerCase;

public final class Array_forall {
  public static void main(final String[] args) {
    final Array<String> a = array("hello", "There", "what", "day", "is", "it");
    final boolean b = a.forall(new F<String, Boolean>() {
      public Boolean f(final String s) {
        return fromString(s).forall(isLowerCase);
      }
    });
    System.out.println(b); // false ("There" is a counter-example; try removing it)
  }
}

Array map §

Maps a function across the array of integers. In this case, the function adds 42 to each element of the array to produce a new array.

import fj.data.Array;
import static fj.data.Array.array;
import static fj.function.Integers.add;
import static fj.pre.Show.arrayShow;
import static fj.pre.Show.intShow;

public final class Array_map {
  public static void main(final String[] args) {
    final Array<Integer> a = array(1, 2, 3);
    final Array<Integer> b = a.map(add.f(42));
    arrayShow(intShow).println(b); // {43,44,45}
  }
}

List map §

Maps a function across a list of integers. This is similar to the Array map. This example adds 42 to each element of the list to produce a new list.

import fj.data.List;
import static fj.data.List.list;
import static fj.function.Integers.add;
import static fj.pre.Show.intShow;
import static fj.pre.Show.listShow;

public final class List_map {
  public static void main(final String[] args) {
    final List<Integer> a = list(1, 2, 3);
    final List<Integer> b = a.map(add.f(42));
    listShow(intShow).println(b); // [43,44,45]
  }
}

List sort §

Sorts the given list by producing a new list using a merge-sort algorithm.

import fj.data.List;
import static fj.data.List.list;
import static fj.pre.Ord.intOrd;
import static fj.pre.Show.intShow;
import static fj.pre.Show.listShow;

public final class List_sort {
  public static void main(final String[] args) {
    final List<Integer> a = list(97, 44, 67, 3, 22, 90, 1, 77, 98, 1078, 6, 64, 6, 79, 42);
    final List<Integer> b = a.sort(intOrd);
    listShow(intShow).println(b); // [1,3,6,6,22,42,44,64,67,77,79,90,97,98,1078]
  }
}

Option bind §

Binds a function across the optional value type. The function checks if the contained value is even and if it is multiples that value by 3 and returns that new value. If the contained value is odd (or if there is no value), then no value is returned (none).

import fj.F;
import fj.data.Option;
import static fj.data.Option.none;
import static fj.data.Option.some;
import static fj.pre.Show.intShow;
import static fj.pre.Show.optionShow;

public final class Option_bind {
  public static void main(final String[] args) {
    final Option<Integer> o1 = some(7);
    final Option<Integer> o2 = some(8);
    final Option<Integer> o3 = none();
    final Option<Integer> p1 = o1.bind(new F<Integer, Option<Integer>>() {
      public Option<Integer> f(final Integer i) {
        if(i % 2 == 0) return some(i * 3); else return none();
      }
    });
    final Option<Integer> p2 = o2.bind(new F<Integer, Option<Integer>>() {
      public Option<Integer> f(final Integer i) {
        if(i % 2 == 0) return some(i * 3); else return none();
      }
    });
    final Option<Integer> p3 = o3.bind(new F<Integer, Option<Integer>>() {
      public Option<Integer> f(final Integer i) {
        if(i % 2 == 0) return some(i * 3); else return none();
      }
    });
    optionShow(intShow).println(p1); // None
    optionShow(intShow).println(p2); // Some(24)
    optionShow(intShow).println(p3); // None
  }
}

Option filter §

Removes the value from the optional value if it does not match a given predicate. In this case the condition for preservation is that the contained value is an even number.

import fj.data.Option;
import static fj.data.Option.none;
import static fj.data.Option.some;
import static fj.function.Integers.even;
import static fj.pre.Show.intShow;
import static fj.pre.Show.optionShow;

public final class Option_filter {
  public static void main(final String[] args) {
    final Option<Integer> o1 = some(7);
    final Option<Integer> o2 = none();
    final Option<Integer> o3 = some(8);
    final Option<Integer> p1 = o1.filter(even);
    final Option<Integer> p2 = o2.filter(even);
    final Option<Integer> p3 = o3.filter(even);
    optionShow(intShow).println(p1); // None
    optionShow(intShow).println(p2); // None
    optionShow(intShow).println(p3); // Some(8)
  }
}

Option map §

Maps a function across the optional value type. The function adds 42 to any contained value.

import fj.data.Option;
import static fj.data.Option.none;
import static fj.data.Option.some;
import static fj.function.Integers.add;
import static fj.pre.Show.intShow;
import static fj.pre.Show.optionShow;

public final class Option_map {
  public static void main(final String[] args) {
    final Option<Integer> o1 = some(7);
    final Option<Integer> o2 = none();
    final Option<Integer> p1 = o1.map(add.f(42));
    final Option<Integer> p2 = o2.map(add.f(42));
    optionShow(intShow).println(p1); // Some(49)
    optionShow(intShow).println(p2); // None
  }
}

HList append §

Appends two heteregeneous lists. The type signature grows proportionally to the size of the list - an unfortunate consequence without type inference.

import static fj.data.hlist.HList.HCons;
import static fj.data.hlist.HList.HNil;
import static fj.data.hlist.HList.HAppend.append;
import static fj.data.hlist.HList.HAppend;
import static fj.data.hlist.HList.nil;

/**
 * Append two heterogeneous lists
 */
public class HList_append {
  public static void main(final String[] args) {
    // The two lists
    final HCons<String, HCons<Integer, HCons<Boolean, HNil>>> a =
      nil().extend(true).extend(3).extend("Foo");
    final HCons<Double, HCons<String, HCons<Integer[], HNil>>> b =
      nil().extend(new Integer[]{1, 2}).extend("Bar").extend(4.0);

    // A lot of type annotation
    final HAppend<HNil, HCons<Double, HCons<String, HCons<Integer[], HNil>>>,
      HCons<Double, HCons<String, HCons<Integer[], HNil>>>> zero = append();
    final HAppend<HCons<Boolean, HNil>, HCons<Double, HCons<String, HCons<Integer[], HNil>>>,
      HCons<Boolean, HCons<Double, HCons<String, HCons<Integer[], HNil>>>>> one = append(zero);
    final HAppend<HCons<Integer, HCons<Boolean, HNil>>, HCons<Double, HCons<String, HCons<Integer[], HNil>>>,
      HCons<Integer, HCons<Boolean, HCons<Double, HCons<String, HCons<Integer[], HNil>>>>>> two = append(one);
    final HAppend<HCons<String, HCons<Integer, HCons<Boolean, HNil>>>,
      HCons<Double, HCons<String, HCons<Integer[], HNil>>>,
      HCons<String, HCons<Integer, HCons<Boolean, HCons<Double, HCons<String, HCons<Integer[], HNil>>>>>>>
      three = append(two);

    // And all of that lets us append one list to the other.
    final HCons<String, HCons<Integer, HCons<Boolean, HCons<Double, HCons<String, HCons<Integer[], HNil>>>>>>
      x = three.append(a, b);

    // And we can access the components of the concatenated list in a type-safe manner
    System.out.println(x.head()); // Foo
    System.out.println(x.tail().tail().tail().tail().head()); // Bar
  }
}

HList foldRight §

Fold across a type-safe heterogeneous list.

import fj.F;
import static fj.Function.identity;
import fj.P2;
import fj.Unit;
import static fj.Unit.unit;
import static java.lang.System.out;

import fj.data.hlist.HList;
import static fj.data.hlist.HList.single;
import static fj.data.hlist.HList.Apply;
import static fj.data.hlist.HList.HFoldr;
import static fj.function.Integers.multiply;
import static fj.function.Integers.add;
import static fj.function.Strings.length;

public class HList_foldRight {

  public static void main(final String[] args) {

    // A heterogeneous list of functions to compose
    final HList.HCons<F<String, Integer>, HList.HCons<F<Integer, Integer>, HList.HCons<F<Integer, Integer>, HList.HNil>>> functions =
      single(add.f(1)).extend(multiply.f(2)).extend(length);

    // A lot of type handwaving to convince Java that this is all going to work
    final Apply<Unit, P2<F<String, Integer>, F<Integer, Integer>>, F<String, Integer>>
      comp1 = Apply.comp();
    final Apply<Unit, P2<F<Integer, Integer>, F<Integer, Integer>>, F<Integer, Integer>>
      comp0 = Apply.comp();
    final HFoldr<Unit, F<Integer, Integer>, HList.HNil, F<Integer, Integer>>
      fold0 = HFoldr.hFoldr();
    final HFoldr<Unit, F<Integer, Integer>, HList.HCons<F<String, Integer>,
          HList.HCons<F<Integer, Integer>, HList.HCons<F<Integer, Integer>, HList.HNil>>>, F<String, Integer>>
      fold2 = HFoldr.hFoldr(comp1, HFoldr.hFoldr(comp0, HFoldr.hFoldr(comp0, fold0)));
    final F<Integer, Integer> id = identity();

    // Compose the list and apply the resulting function to a value.
    // Unit is used because composition has only one possible implementation.
    out.println(fold2.foldRight(unit(), id, functions).f("abc")); // 7
  }
}