日記

updated: 2021-03-18

「関数型言語にはストラテジパターンは存在しない(パターンと言う必要がないほど当たり前に存在する)」と言われたことがある。 少し引っかかることがあったので、ストラテジパターンが何をしているのかを考えた。

ストラテジパターンは以下の2つのことをしているんじゃないかと思っている。

  • インタフェースを用いて入れ替え可能にする
  • インタフェースに名前をつける

このうち前者については、関数型が第一級として扱える関数型言語では当たり前だろう。 一方、後者については関数型言語といっても自然には存在しないだろうと思う。

インタフェースを用いて入れ替え可能にする

関数型を第一級として扱える関数型言語では当たり前だとは言ったけれど、 Java 等でも関数型を第一級として扱えるのでインタフェースを定義しなくてもいい。 TECHSCOREのコードを参考に Java 風に書いてみた。 書いてみているけれど、利点はないと思う。

public class MyClass{
    private Func<Human, Human, int> comparator = null;

    public MyClass(Func<Human, Human, int> comparator){
        this.comparator = comparator;
    }

    public int compare(Human h1,Human h2){
        return comparator.compare(h1,h2);
    }
}

インタフェースに名前をつける

関数型言語では関数型を第一級として扱えるので自然とストラテジパターンのようなものはできる。 しかし、できるとは言うものの、インタフェースとして名前がついているわけではないので少し情報が落ちているように思う。

例えば、上述の TECHSCORE に出てきた Human 2つを比較して int を返す Comparator を、 Haskell で定義してみる。

type Comparator = Human -> Human -> Int

AgeComparator :: Comparator
AgeComparator h1 h2 = 
  case diff of
    _ | diff < 0 = -1
    _ | diff == 0 = 0
    _ | diff > 0 = 1
  where
    diff = (age h1) - (age h2)

終わり

Java 風の関数型コードと Haskell 風のパターンコードを書いてみた。 わざわざ他方に寄せた雰囲気のコードを書くと分かりづらいな。