2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[Java1.8] UnaryOperatorの結合関数の勉強

Last updated at Posted at 2015-09-22

UnaryOperatorのお勉強です。

UnaryOperatorとUnaryOperatorを結合した関数はどのようにかけるだろうか?

いろいろやってみる

public interface UnaryOperatorConnector<T> extends UnaryOperator<T>{
    public UnaryOperator<T> apply( UnaryOperator<T> t);
}

こうかな・・・

public class UnaryOperatorConnectorTest{
    @Test
    public void test(){
        UnaryOperatorConnector<String> o2 = s -> s + "a";
}

あれ???うーん・・・・・

あ、composeね。

public class UnaryOperatorConnectorTest{
    @Test
    public void test(){
        UnarryOperator<String> o1 = s -> s+"*";
        UnaryOperatorConnector<String> o2 = o1.compose( s -> s+ "*" );
}

あれ???うーん・・・・・

UnaryOperator<String> op1 = s -> s + "*";
UnaryOperator<String> op2 = s -> s + "+";
Function<String,String> uo = op2.andThen(op1);

OKだ・・・

UnaryOperator<String> op1 = s -> s + "*";
Function<String,String> uo2 = op2.andThen(s -> s+"*");

OKだ・・・
つまり、UnaryOperator.composeがFunctionを返してしまうのがおかしいんですかね。

結論

つまり、一旦Functionで受け取ってUnaryOperatorに変換しなければならないらしい。

UnaryOperators.java
public class UnaryOperators<T> implements UnaryOperator<T> {
    private Function<T,T>[] operators;

    public UnaryOperators(UnaryOperator<T>... operators){
        this.operators = operators;
    }
   @Override
    public T apply(T t) {
        return Arrays.asList(operators).stream().reduce (Function::compose ).get().apply(t) ;
    }
    public static <T> UnaryOperator<T> connect(UnaryOperator<T>... ops){
        return x -> Arrays.<Function<T,T>>asList(ops).stream().reduce( Function::compose ).get().apply(x);
    }
}
public class UnaryOperatorsTest{
   @Test
    public void test2(){
        UnaryOperator<String> op1 = s -> s + "*";
        UnaryOperator<String> op2 = s -> s + "+";

        UnaryOperator<String> op3 = new UnaryOperators<>(op1,op2);
        UnaryOperator<String> op4 = UnaryOperators.connect(op1,op2);

        System.out.println(op3.apply("xxx"));
        System.out.println(op4.apply("yyy"));
    }
}

実行結果

xxx+*
yyy+*

関数をデータのように扱い始めると、頭が沸騰しそうです。

こういうことをやっていると、「関数もオブジェクトなんだな」という事を実感します。
むしろ関数型言語側からいえば、「オブジェクトもまた関数なんだよ」と言う事かもしれませんが。

というか

    public static <T> UnaryOperator<T> connect(UnaryOperator<T>... ops){
        return Arrays.<Function<T,T>>asList(ops).stream().reduce( Function::compose ).get()::apply;
    }

こっちのほうがいいか。
クールな書き方があれば教えてください。

2
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?