少し考え過ぎだと思います。バイファンクターは、2 パラメーター ファンクターのようなものです。Gibbons と Oliveira のアイデアは、bifanctor の 1 つのアプリケーションにすぎません。ちょうど標準的な再帰スキームの動物園が functor の 1 つのアプリケーションにすぎないのと同じです。
class Bifunctor f where
bimap :: (a -> c) -> (b -> d) -> f a b -> f c d
Bifunctor
s には種類が* -> * -> *
あり、両方のパラメーターを共変的にマッピングできます。これを、共変的にマッピングできるFunctor
パラメーター ( ) が 1 つしかない通常の s と比較してください。f :: * -> *
たとえば、Either
の通常のFunctor
インスタンスについて考えてみましょう。fmap
2 番目の型パラメータのみを許可します。Right
値はマップされ、Left
値はそのままになります。
instance Functor (Either a) where
fmap f (Left x) = Left x
fmap f (Right y) = Right (f y)
ただし、そのBifunctor
インスタンスを使用すると、合計の両方の半分をマップできます。
instance Bifunctor Either where
bimap f g (Left x) = Left (f x)
bimap f g (Right y) = Right (g y)
同様に、タプルの場合:(,)
のFunctor
インスタンスでは、2 番目のコンポーネントのみをマップBifunctor
できますが、両方の部分をマップできます。
instance Functor ((,) a) where
fmap f (x, y) = (x, f y)
instance Bifunctor (,) where
bimap f g (x, y) = (f x, g y)
Maybe
あなたが言及した は、パラメーターが1つしかないため、バイファンクターのフレームワークに適合しないことに注意してください。
の問題でFix
は、バイファンクターの固定小数点により、ほとんどのコンテナーのような構造など、関数型パラメーターを持つ再帰型を特徴付けることができます。例としてリストを使用してみましょう。
newtype Fix f = Fix { unFix :: f (Fix f) }
data ListF a r = Nil_ | Cons_ a r deriving Functor
type List a = Fix (ListF a)
上記のように、標準の functorial を使用すると、 forのパラメーターについて何も知らないため、forFix
のインスタンスの一般的な派生はありません。つまり、種類が間違っているため、ようなものを書くことはできません。おそらく次を使用して、 for リストを手動でクランクする必要があります。Functor
List
Fix
List
a
instance Something f => Functor (Fix f)
Fix
map
cata
map :: (a -> b) -> List a -> List b
map f = cata phi
where phi Nil_ = Fix Nil_
phi Cons_ x r = Fix $ Cons_ (f x) r
の二関数バージョンでFix
は、 のインスタンスが許可されますFunctor
。Fix
bifunctor のパラメーターの 1 つを使用して再帰的な出現をプラグインしFix f a
、もう 1 つを結果のデータ型の functorial パラメーターの代わりに使用します。
newtype Fix f a = Fix { unFix :: f a (Fix f a) }
instance Bifunctor f => Functor (Fix f) where
fmap f = Fix . bimap f (fmap f) . unFix
したがって、次のように記述できます。
deriveBifunctor ''ListF
type List = Fix ListF
Functor
無料でインスタンスを取得します。
map :: (a -> b) -> List a -> List b
map = fmap
もちろん、複数のパラメーターを持つ再帰構造を一般的に使用したい場合は、tri-functor、quad-functor などに一般化する必要があります...これは明らかに持続可能ではなく、多くの作業が必要です (より高度なプログラミングでは言語) は、型を特徴付けるためのより柔軟なシステムの設計に投入されています。