arahfahrrad
arahfahrrad

Reputation: 165

Lambda Expressions functional programming

I have to programm regular expression with lambda expressions for the university. I got stuck by 2 methods in a method.

here is my code:

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;};

what I want to do in the And method is: Char(Char.apply("a")) -> I want to call the function f2 with the f1 as a parameter. the Call of the And Method have to look like:

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

Upvotes: 3

Views: 189

Answers (2)

ZhongYu
ZhongYu

Reputation: 19682

I guess this is what you want

    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 is not necessary though, see Function.andThen method

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

Unfortunately, there is no "curry"; otherwise, we could do this

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

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

It's better off if you design your own functional interfaces, with needed methods like curry.

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

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

Upvotes: 1

tobias_k
tobias_k

Reputation: 82929

If I understand the question correctly, you want to create a function that compones a new function, executing one function with the result of another function. The best way to do this in a lambda would be to return a new lambda.

Try something like this:

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

Example:

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"));

Output is FOOFOO.


Concerning your concrete example

the Call of the And Method have to look like: And.apply(Char.apply("a"), Char.apply("b");

I do not know exactly what you are trying to do, but I don't think this will work, given your current implementation of Char. It seems like you want to compose a lambda to remove a with another to remove b, but instead Char.apply("a") will not create another function, but actually remove "a" from your ausdruck String! Instead, your Char lambda should probably also return another lambda, and that lambda should not modify some static variable, but take and return another String parameter.

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"));

Output is sh.


Finally, in case you want to use this with anything other than just String, it might make sense to make compose an actual method instead of a lambda, so you can make use of generics. Also, you can make this a bit simpler by using andThen:

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

Upvotes: 1

Related Questions