【问题标题】:Lambda Expressions functional programmingLambda 表达式函数式编程
【发布时间】:2015-06-13 17:00:14
【问题描述】:

我必须为大学编写带有 lambda 表达式的正则表达式。我被一种方法中的两种方法卡住了。

这是我的代码:

static String ausdruck = "abcd";

public static Function<String, String> Char = (c) -> {
    return (ausdruck.startsWith(c)) ? ausdruck = ausdruck.substring(1,
            ausdruck.length()) : "Value Error";
};

public static BiFunction<Function<String, String>, 
                         Function<String, String>, 
                         Function<String, String>> 
                And = (f1, f2) -> {return null;};

我想在And 方法中做的是:Char(Char.apply("a")) -> 我想以f1 作为参数调用函数f2。 And 方法的调用必须如下所示:

And.apply(Char.apply("a"), Char.apply("b"));

【问题讨论】:

标签: java regex lambda functional-programming


【解决方案1】:

我想这就是你想要的

    Func<Str,Str> f = and( comsume("a"), consume("b") );
    f.apply("abcd"); // "cd"


Func<Str,Str> consume(String x)
    return input->{ 
        if(input.startsWith(x)) return input.substring(x.length());
        else throws new IllegalArgument()
    };


Func<Str,Str> and(Fun<Str,Str> f1, Func<Str,Str> f2)
    return input-> f2.apply(f1.apply(input))

and 不是必需的,请参阅Function.andThen 方法

    f = consume("a").andThen( consume("b) )

不幸的是,没有“咖喱”;否则,我们可以这样做

    f = consume2.curry("a") .andThen (  consume2.curry("b") );

static BiFunc<Str,Str,Str> consume2 = (input,x)-> {...return input.substring(x.length()); ..

如果您设计自己的函数式接口,最好使用 curry 等所需的方法。

interface F1
    String apply(String);
    F1 and(F1);

interface F2
    String apply(String,String);
    F1 curry(String);

【讨论】:

    【解决方案2】:

    如果我正确理解了这个问题,您想创建一个函数来组成一个新函数,执行一个函数和另一个函数的结果。在 lambda 中执行此操作的最佳方法是返回一个新的 lambda。

    试试这样的:

    BiFunction<Function<String, String>, Function<String, String>, Function<String, String>> compose =
                (f1, f2) -> (a -> f2.apply(f1.apply(a)));
    

    例子:

    Function<String, String> upper = s -> s.toUpperCase();
    Function<String, String> twice = s -> s + s;
    Function<String, String> upperTwice = compose.apply(upper, twice);
    System.out.println(upperTwice.apply("foo"));
    

    输出是FOOFOO


    关于你的具体例子

    And 方法的调用必须如下所示: And.apply(Char.apply("a"), Char.apply("b");

    我不知道你到底想做什么,但考虑到你当前的Char 实现,我认为这不会奏效。似乎您想组合一个 lambda 来删除 a 和另一个以删除 b,但 Char.apply("a") 不会创建另一个函数,而是实际上从您的 ausdruck 字符串中删除 "a"!相反,您的 Char lambda 可能还应该返回另一个 lambda,并且该 lambda 不应该修改某些 static 变量,而是接受并返回另一个 String 参数。

    Function<String, Function<String, String>> stripChar = 
                c -> (s -> s.startsWith(c) ? s.substring(1) : "ERROR");
    Function<String, String> stripAandC = compose.apply(stripChar.apply("c"), stripChar.apply("a"));
    System.out.println(stripAandC.apply("cash"));
    

    输出为sh


    最后,如果您想将它与 String 以外的任何东西一起使用,将 compose 设为实际方法而不是 lambda 可能是有意义的,因此您可以使用泛型。此外,您可以使用andThen 使这更简单:

    public static <A, B, C> Function<A, C> compose(Function<A, B> f1, Function<B,C> f2){
        return f1.andThen(f2);
    }
    

    【讨论】: