class (Functor f, Functor g) => Adjunction f g | f -> g, g -> f where unit :: a -> g (f a) counit :: f (g a) -> a
ここで一行目の
Adjunction f g | f -> g, g -> f
で縦棒|
は何を表しているんですか?
Haskellのクラス宣言における縦棒
|
は関数従属性(Functional Dependency)を表しています。具体的にはAdjunction f g | f -> g, g -> f
という宣言は、f
が決まればg
が一意に決まり、逆にg
が決まればf
が一意に決まるという依存関係を表しています。関数従属性は、型クラスのインスタンスが一意に決定できるようにするためのものです。もし同じ型に対して複数のインスタンスが存在すると、コンパイラはどのインスタンスを選べば良いか判断できずエラーとなります。関数従属性を用いることで、特定の型が与えられた時に対応するインスタンスが一意に定まることを保証します。この機能は、Haskellのマルチパラメータ型クラス(Multi-parameter Type Classes)と組み合わせて使われます。Source 2
具体的に
Adjunction f g | f -> g, g -> f
という宣言を見てみましょう。これはAdjunction
型クラスがf
とg
の2つの型パラメータを持つマルチパラメータ型クラスであり、f
がg
に、g
がf
に依存していることを示しています。これにより、f
かg
のどちらか一方が決まれば、もう一方の型も一意に決まることが保証されます。Source 1例えば、以下のような型クラスのインスタンス宣言があったとします。
instance Adjunction Maybe [] where unit = return counit = head
この場合、関数従属性
f -> g, g -> f
のおかげで、f
がMaybe
であるならばg
は[]
でなければならず、逆にg
が[]
であるならばf
はMaybe
でなければならないと決まります。したがって、f
やg
の型が決まった時点で、Adjunction
のインスタンスが一意に決まることが保証されます。
- Rustの関連型っぽい?