Chapter 02

1.1 関数としての射

さのたけと
さのたけと
2021.05.04に更新

すでに話が抽象的になりすぎただろうか? でも絶望しないでほしい.具体的な話をしよう.射は関数であると考えよう.関数 f は型 A の引数を取り,型 B の値を返すとする.もう一つ関数 gB の引数を取り C の値を返すとする.すると f の戻り値を g に渡すことができる.これで A を取り C を返す関数ができた.

数学では,このような合成は関数の間の小さな丸で表される:g \circ f.合成は 右から左 の順になっていることに注意しよう.この記法は紛らわしく感じる人もいるだろう.あなたは Unix でのパイプ記法に馴染みがあるかも知れない.例えば次のような:

lsof | grep Chrome

あるいは F# における chevron >> に.これらはどちらも 左から右へ 合成される.しかし数学や Haskell においては,関数は 右から左 に合成される.g \circ f を "g after f" と読むと分かりやすいだろう[1]

このことをもっと分かりやすくするため,C のコードを書いてみよう.関数 f は型 A の引数を取り型 B の値を返す:

B f(A a);

そしてもう一つ:

C g(B b);

これらの合成は:

C g_after_f(A a)
{
    return g(f(a));
}

今度は C だが,再び 右から左へ の合成 g(f(a)); が見られる.

ここで C++ Standard Library のテンプレートで,二つの関数を取ってそれらの合成を返すものがあると言えれば良いのだが,残念ながらそれがない.なので代わりに Haskell でやってみよう.ここに A から B への関数の宣言がある:

f :: A -> B

同様に:

g :: B -> C

これらの合成は:

g . f

いかに Haskell で物事がシンプルに表現されるか見てしまうと,C++ で関数に関する概念を素直に表現できない事実に少し戸惑ってしまう.さらに言えば,Haskell では Unicode 文字が使えるので,合成は次のようにも書ける:

gf

さらに Unicode のダブルコロン[2]や矢印も使える:

f :: AB

これが Haskell の第一のレッスンだ:ダブルコロンは "…は次の型を持つ…" の意味である.関数型は二つの型の間に矢印を入れることで作られる.二つの関数の合成は,それらの間にピリオド . (または小さな丸 )を入れることで得られる.

(和訳:@taketo1024

脚注
  1. 訳注:残念ながらこの順に読める適切な日本語訳はなさそう. ↩︎

  2. ダブルコロンの Unicode 文字が見つけられなかったので普通のコロン2個を書く. ↩︎