为什么我的类型类不满足函数依赖?

问题描述 投票:0回答:1

我尝试创建一种方法来剥离通用代表的元信息。 在创建类型类并为每个使用的 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
haskell generics typeclass functional-dependencies
1个回答
0
投票

我尝试从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 覆盖条件

© www.soinside.com 2019 - 2024. All rights reserved.