我相信没有好的类型术语
Leibniz Bool (Either One One)
。确实,有“奇怪的”
f
这是我们不能进行转换的地方;一个微不足道的例子是
Bool :~: Bool
有人居住,但
Bool :~: Either One One
不是,如果
f = (:~:) Bool
那么就没有类型的函数
f Bool -> f (Either One One)
。
但是如果你修改
Leibniz
略微:
newtype Leibniz a b = Leibniz {unLeibniz :: forall f. IsoFunctor f => f a -> f b}
在这里
IsoFunctor
新班级像
Functor
除了它需要两个方向上的纯映射:
class IsoFunctor f where isomap :: (a -> b) -> (b -> a) -> f a -> f b
这个类排除了参数是名义的而不是代表性的类型,比如
(:~:) Bool
。(而且,在另一个方向上,实例总是可以为具有正确类型并且在其论证中具有代表性的类型编写。)然后我们可以写道:
p :: Leibniz Bool (Either One One)
p = Leibniz (isomap u v)
不幸的是,编译器不能(而且通常不能)保证
u
和
v
相反。