Функциональная функция Java связывает функцию arity-2 (F2) с опциями - PullRequest
1 голос
/ 19 мая 2011

Я понимаю базовый синтаксис привязки для Option с функциональной Java как

Option.some(2).bind(new F<Integer,Option<Integer>>(){
    public Option<Integer>f(Integer i){
        return Option.some(i/2);
    }
};

, который хорошо работает для функций с одним входом, но я не могу понять, как использовать несколько функций ввода (таких как F2, F3,так далее).

т.е.:

new F2<Integer,Integer,Option<Integer>>(){
    public Option<Integer>f(Integer a,Integer b){
        return Option.some(a/b);
    }
} 

Я знаю, что что-то упустил, но документация немного скудна.Идеи?

Ответы [ 3 ]

0 голосов
/ 19 мая 2011

Прорыв,

Хитрость в том, что вам нужно развернуть функцию arity и связать ее с произведением ваших опций.

Так в примере:

реализация arity-5

import fj.F;
import fj.F5;
import fj.P5;

public abstract class F5Optional<At, Bt, Ct, Dt, Et, Ft> extends F5<At, Bt, Ct, Dt, Et, Ft> {

    public final F<P5<At, Bt, Ct, Dt, Et>, Ft> tupleize() {
        return new F<P5<At, Bt, Ct, Dt, Et>, Ft>() {

            @Override
            public Ft f(final P5<At, Bt, Ct, Dt, Et> p) {
                return F5Optional.this.f(p._1(), p._2(), p._3(), p._4(), p._5());
            }
        };
    }

}

использование:

    F5Optional<Integer, Integer, Integer, Integer, Integer, Option<Integer>> f5 = new F5Optional<Integer, Integer, Integer, Integer, Integer, Option<Integer>>() {

        @Override
        public Option<Integer> f(Integer a, Integer b, Integer c, Integer d, Integer e) {
            return Option.some(a + b + c + d + e);
        }
    };
    Option<Integer> test2 = b.bindProduct(Option.some(1), Option.some(1), Option.some(1), Option.some(1)).bind(f5.tupleize());
    Assert.assertTrue(new Integer(8).equals(test2.toNull()));

    Option<Integer> nullInteger = Option.none();
    Option<Integer> test3 = b.bindProduct(nullInteger, Option.some(1), Option.some(1), Option.some(1)).bind(f5.tupleize());
    Assert.assertTrue(test3.isNone());
0 голосов
/ 27 октября 2013

Ваше решение работает, используя кортеж (один параметр) вместо двух параметров и работая с ними. Альтернативным, может быть, лучшим подходом было бы (я второй Диего на этом) работать с частичными функциями и карри. Например, вы можете сделать что-то вроде:

public final F2<Integer, Integer, Option<Integer>> sumInteger() {
    return new F2<Integer,Integer,Option<Integer>>() {
        @Override
        public Option<Integer> f(Integer a, Integer b) {
            /* you logic here */
        }
    }; 
}

public final F<Integer, Option<Integer>> partialSumInteger(final F2<Integer, Integer, Option<Integer>> f2, final Integer fixed) {
    return Function.partialApply2(f2.curry(), fixed);
}

А затем передайте свою теперь 1-арную функцию для связывания. Взгляните на класс Functional Java fj.Function, он содержит функции для каррирования и частичного применения ваших функций n-арности. Я согласен, что документация не самая лучшая.

0 голосов
/ 19 мая 2011

Я не уверен в том, что вы спрашиваете, но если вы пытаетесь связать функцию с двумя арностями в Option, вам следует частично применить функцию с двумя арностями перед ее связыванием. Таким образом, это приведет к унарной функции с фиксированным первым параметром:

(new F2<...>{ ... }).f(5)

(привязать первый параметр к 5, возвращая новую унарную функцию).

Я искал и не нашел частичного аппликатора для параметра second . Это странно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...