我一直在尝试对数据类型进行一些抽象,并且遇到了 GHC 泛型的情况,这似乎有点奇怪。这是我的基本声明集:
class GFields f where
gfields :: f a -> [String]
instance (GFields c) => GFields (D1 i c) where
gfields = gfields . unM1
instance (GFields fs) => GFields (C1 i fs) where
gfields = gfields . unM1
instance (GFields f, GFields fs) => GFields (f :*: fs) where
gfields (f :*: fs) = gfields f ++ gfields fs
instance (Selector s) => GFields (S1 s r) where
gfields = (:[]) . selName
data Thing = Thing { foo :: String, bar :: Int }
deriving (Generic)
Prelude.undefined
如果我给它一个未定义的值,尝试在 GHCi 中使用它会给我:
> gfields $ from (undefined :: Thing)
*** Exception: Prelude.undefined
但是,如果我尝试手动运行一些预期的实例(只抓取一个字段),我会得到我所期望的:
> selName $ (\(l :*: r) -> l) $ unM1 $ unM1 $ from (undefined :: Thing)
"foo"
为什么我Prelude.undefined
进了一个,而不是另一个?