我尝试创建一种方法来剥离通用代表的元信息。 在创建类型类并为每个使用的 Rep 类型编写实例时,我遇到一个错误,指出其中两个实例 (:+:, M1) 不满足函数依赖关系。我不明白这个。
这是我的代码:
{-# LANGUAGE FunctionalDependencies #-}
module Generics where
import GHC.Generics
class WithoutMeta f f' | f -> f' where
withoutMeta :: f p -> f' p
instance WithoutMeta V1 V1 where
withoutMeta = id
instance WithoutMeta U1 U1 where
withoutMeta = id
instance (WithoutMeta f f', WithoutMeta g g') => WithoutMeta (f :+: g) (f' :+: g') where
withoutMeta (L1 l) = L1 $ withoutMeta l
withoutMeta (R1 r) = R1 $ withoutMeta r
instance (WithoutMeta f f', WithoutMeta g g') => WithoutMeta (f :*: g) (f' :*: g') where
withoutMeta (f :*: g) = withoutMeta f :*: withoutMeta g
instance WithoutMeta (K1 i a) (K1 i a) where
withoutMeta = id
instance WithoutMeta f f' => WithoutMeta (M1 i c f) f' where
withoutMeta (M1 f) = withoutMeta f
我尝试从fundeps切换到type family,它似乎可以编译。类型系列对我来说更具可读性。
{-# LANGUAGE TypeFamilies #-}
import GHC.Generics
import Data.Kind
class WithoutMeta f where
type WM f :: Type -> Type
withoutMeta :: f p -> WM f p
instance WithoutMeta V1 where
type WM V1 = V1
withoutMeta = id
instance WithoutMeta U1 where
type WM U1 = U1
withoutMeta = id
instance (WithoutMeta f, WithoutMeta g) => WithoutMeta (f :+: g) where
type WM (f :+: g) = (WM f :+: WM g)
withoutMeta (L1 l) = L1 $ withoutMeta l
withoutMeta (R1 r) = R1 $ withoutMeta r
instance (WithoutMeta f, WithoutMeta g) => WithoutMeta (f :*: g) where
type WM (f :*: g) = (WM f :*: WM g)
withoutMeta (f :*: g) = withoutMeta f :*: withoutMeta g
instance WithoutMeta (K1 i a) where
type WM (K1 i a) = (K1 i a)
withoutMeta = id
instance WithoutMeta f => WithoutMeta (M1 i c f) where
type WM (M1 i c f) = WM f
withoutMeta (M1 f) = withoutMeta f
如果您想继续使用fundeps,可以尝试打开
UndecidableInstances
。如果没有这个,您的代码似乎不满足确保终止的 GHC 覆盖条件。