プログラマーのための圏論 の第 8 章に頭を悩ませています。
セクション 8.3 で、Bartosz はこの型を定義しています。
newtype BiComp bf fu gu a b = BiComp (bf (fu a) (gu b))
ここで、Haskell を少し理解している場合、bf
、、fu
およびは種類のgu
型コンストラクターでありbf
、種類の型コンストラクター ( orと同様) であり、 、 およびは種類の一般的な型です。の左側は書き込みが長すぎる種類の型コンストラクターですが、右側は値コンストラクターであるため、型です。(* -> *) -> (* -> *) -> * -> * -> *
fu
gu
* -> *
Maybe
[]
a
b
*
BiComp
=
BiComp
(bf (fu a) (gu b)) -> BiComp bf fu gu a b
次に、作成者は、型コンストラクターのパラメーターが aであり、型コンストラクターおよびがsであるという条件で、 andにBiComp
バイファンクターを作成します。a
b
bf
Bifunctor
fu
gu
Functor
instance (Bifunctor bf, Functor fu, Functor gu) => Bifunctor (BiComp bf fu gu) where
bimap f1 f2 (BiComp x) = BiComp ((bimap (fmap f1) (fmap f2)) x)
これまでのところとても良いので、現時点ではすべてが妥当に思えます。型コンストラクターと値コンストラクターに同じ名前を使用すると、おそらく迷子になることを除いて。
今、私は次の観察をしたくなる。
- 定義の
bimap
右側にあるのは、制約を利用するものです。それは、型コンストラクターが実際に何であれ、インスタンスでbimap
定義されていると想定されるものです。したがって、これには type があります。これは、8.1 で提示された型の署名にすぎないため、次の例ほど興味深いものではないと思います。Bifunctor
bf
bimap
(a -> a') -> (b -> b') -> bf a b -> bf a' b'
bimap
Bifunctor
class
- 代わりに、
bimap
左側は、4 番目と 5 番目のパラメーターでBiComp
aを作成するために定義しているものです。Bifunctor
引数f1
とf2
は、 の 4 番目と 5 番目のパラメータであるタイプのエンティティに作用する必要がある関数ですBiComp
。したがって、このbimap
タイプは(a -> a') -> (b -> b') -> BiComp bf fu gu a b -> BiComp bf fu gu a' b'
です。
これは正しいです?
もしそうなら、私は次のことを理解していません
bimap :: (fu a -> fu a') -> (gu b -> gu b') -> bf (fu a) (gu b) -> bf (fu a') (gu b')
これは、= 、=などでbimap
書かれていることを除いて、上の箇条書きで書いた右側の の型だからです。a
fu a
a'
fu a'
私は何かを見逃していますか(または考えすぎています...)?