import java.util.List;
import java.util.function.BiFunction;

public class Fold {

  static <E,R> R falte(Iterable<E> xs, R start, BiFunction<R, E, R> f) {
    var result = start;
    for (var x : xs) {
      result = f.apply(result, x);
    }
    return result;
  }

  public static void main(String[] args) {
    var xs = List.of("Das", "Pferd", "frisst", "keinen", "Gurkensalat");
    System.out.println(falte(xs, 0, (result, x) -> result + 1));
    System.out.println(falte(xs, "", (result, x) -> result + " " + x));
    System.out.println(falte(xs, "", (r, x) -> r.length() > x.length() ? r : x));
    var s = "Pferd";
    System.out.println(falte(xs, false, (r, x) -> r || x.equals(s)));
    var ys = List.of(1,2,3,4,5,6,7,8,9,10);
    System.out.println(falte(ys,0,(r,x)->r+x));
    
    var longest
     = xs.parallelStream()
       .reduce("", (r, x) -> r.length() > x.length() ? r : x);
    var conc = xs.parallelStream()
        .reduce("", (result, x) -> result + " " + x);
    System.out.println(longest);
    System.out.println(conc);
    System.out.println(ys.stream().reduce(0,(r,x)->r+x));
    var l = xs.parallelStream().reduce(0, (r,x)->r+1, (x,y)->x+y);
    
    System.out.println(l);
    
    ys.parallelStream().forEach(y-> System.out.println(y*y));
  }

}
