是否有可能Enum
使用GHC泛型重新实现类型类的派生?
起初,它看起来很简单:
data Foo -- representation without metadata (wrong):
= Foo -- L1 U1
| Bar -- R1 (L1 U1)
| Baz -- R1 (R1 (L1 U1))
| Quux -- R1 (R1 (R1 U1))
deriving (Show, Eq, Generic)
-- Rep Foo p = (U1 :+: (U1 :+: (U1 :+: U1))) p
instance Enum Foo where
toEnum = undefined -- FIXME
fromEnum = gfromEnum . from
class GEnum f where
gfromEnum :: f p -> Int
instance GEnum U1 where
gfromEnum U1 = 0
instance GEnum f => GEnum (M1 i t f) where
gfromEnum (M1 x) = gfromEnum x
instance (GEnum x, GEnum y) => GEnum (x :+: y) where
gfromEnum (L1 x) = gfromEnum x
gfromEnum (R1 y) = 1 + gfromEnum y
但是,这不会起作用:
?> fromEnum Foo
0
?> fromEnum Bar
1
?> fromEnum Baz
1
?> fromEnum Quux
2
这是因为我们不能依赖于如何对参数(:+:)
进行分组.在这种情况下,似乎它们嵌套如下:
((U1 :+: U1) :+: (U1 :+: U1)) p
那么,是否可以推导出Enum
使用Generics
?如果有,怎么样?