假设我们有一些类Foo
,这样的实例Foo f
为我们提供了实现 和 所需Functor f
的Foldable f
一切Traversable f
。为了避免重叠的实例,可以在 newtype 包装器之间Foo
和下面见证这种关系:Functor, Foldable, Traversable
type Foo :: (Type -> Type) -> Constraint
class Foo f
where
{- ... -}
type FoonessOf :: (Type -> Type) -> Type -> Type
newtype FoonessOf f a = FoonessOf (f a)
instance Foo f => Functor (FoonessOf f)
where
fmap = _
instance Foo f => Foldable (FoonessOf f)
where
foldMap = _
instance Foo f => Traversable (FoonessOf f)
where
traverse = _
现在假设我们有一些类型构造函数:
data Bar a = Bar {- ... -}
这样有一个:
instance Foo Bar
where
{- ... -}
我们想装备它的“ -ness”Bar
所暗示的实例。Foo
既然Bar a
是Coercible
to FoonessOf Bar a
,我们希望能够推导出via
实例FoonessOf Bar
:
deriving via (FoonessOf Bar) instance Functor Bar
deriving via (FoonessOf Bar) instance Foldable Bar
这适用于类型类,例如Functor
和Foldable
不幸的是,当我们尝试对 做同样的事情时Traversable
,事情就出错了:
[typecheck -Wdeferred-type-errors] [E] • Couldn't match representation of type ‘f1 (Foo Bar a1)’
with that of ‘f1 (Bar a1)’
arising from a use of ‘ghc-prim-0.6.1:GHC.Prim.coerce’
NB: We cannot know what roles the parameters to ‘f1’ have;
we must assume that the role is nominal
• In the expression:
ghc-prim-0.6.1:GHC.Prim.coerce
@(Foo Bar (f a) -> f (Foo Bar a)) @(Bar (f a) -> f (Bar a))
(sequenceA @(Foo Bar)) ::
forall (f :: TYPE ghc-prim-0.6.1:GHC.Types.LiftedRep
-> TYPE ghc-prim-0.6.1:GHC.Types.LiftedRep)
(a :: TYPE ghc-prim-0.6.1:GHC.Types.LiftedRep).
Applicative f => Bar (f a) -> f (Bar a)
In an equation for ‘sequenceA’:
sequenceA
= ghc-prim-0.6.1:GHC.Prim.coerce
@(Foo Bar (f a) -> f (Foo Bar a)) @(Bar (f a) -> f (Bar a))
(sequenceA @(Foo Bar)) ::
forall (f :: TYPE ghc-prim-0.6.1:GHC.Types.LiftedRep
-> TYPE ghc-prim-0.6.1:GHC.Types.LiftedRep)
(a :: TYPE ghc-prim-0.6.1:GHC.Types.LiftedRep).
Applicative f => Bar (f a) -> f (Bar a)
When typechecking the code for ‘sequenceA’
in a derived instance for ‘Traversable Bar’:
To see the code I am typechecking, use -ddump-deriv
In the instance declaration for ‘Traversable Bar’
——————————————————————————————————————————————————————————————————————————————
...
所以我的问题是:
- 是否可以通过实例提出其他一些派生方案
Traversable Bar
? - 是否有可能对
Traversable
可以通过新类型派生的类进行一些修改?