Edward Kmett 的实验性角色包提供了各种用于解除强制的实用程序,其中一些我已粘贴在本问题的末尾。包中的关键类是
class Representational (t :: k1 -> k2) where
-- | An argument is representational if you can lift a coercion of the argument into one of the whole
rep :: Coercion a b -> Coercion (t a) (t b)
给定类型
newtype Fix p a = In {out :: p (Fix p a) a}
我希望写一些类似的东西
instance Representational p => Representational (Fix p)
我相信以下应该有效,除了一个缺失的部分。我也有点担心,这bar
可能足够严格,以至于把所有东西都扔进一个无限循环。
-- With {-# LANGUAGE PolyKinds, ScopedTypeVariables, etc.)
import Data.Type.Coercion
import Data.Coerce
import Data.Roles
instance Representational p => Representational (Fix p) where
rep :: forall a b . Coercion a b -> Coercion (Fix p a) (Fix p b)
rep x = sym blah . quux . baz . blah
where
bar :: Coercion (p (Fix p a)) (p (Fix p b))
bar = rep (rep x)
baz :: Coercion (p (Fix p a) a) (p (Fix p b) a)
baz = eta bar
quux :: Coercion (p (Fix p b) a) (p (Fix p b) b)
quux = undefined -- ?????????
blah :: forall x . Coercion (Fix p x) (p (Fix p x) x)
blah = Coercion
点点滴滴roles
eta :: forall (f :: x -> y) (g :: x -> y) (a :: x).
Coercion f g -> Coercion (f a) (g a)
instance Representational Coercion
instance Representational f => Representational (Compose f)