rank2classes包提供了一个版本,Functor
其映射函数似乎是类型构造函数之间的自然转换。
按照这个想法,这是 2 级版本Bifunctor
:
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE StandaloneKindSignatures #-}
import Data.Kind
type Rank2Bifunctor :: ((Type -> Type) -> (Type -> Type) -> Type) -> Constraint
class Rank2Bifunctor b where
rank2bimap ::
(forall x. p x -> p' x) -> (forall x. q x -> q' x) -> b p q -> b p' q'
似乎很清楚,Foo
可以给这种类型一个Rank2Bifunctor
实例:
data Foo f g = Foo (f Int) (g Int)
instance Rank2Bifunctor Foo where
rank2bimap tleft tright (Foo f g) = Foo (tleft f) (tright g)
但是Bar
这种嵌套f
和的类型呢g
:
data Bar f g = Bar (f (g Int))
对于初学者来说,似乎我们需要Functor p
在 , 的签名中要求rank2bimap
能够转换.g
f
是Bar
有效的“rank-2 双函子”吗?