(与Using custom instance when deriving an instance via GeneralizedNewtypeDeriving相关)。假设我有:
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Main (main) where
data Cat = Cat String deriving (Show)
newtype Dolphin = Dolphin Cat deriving (Info,Show)
class Info a where
info :: a -> (a,String)
instance Info Cat where
info a = (a,show a)
main = do
print $ info (Cat "mammal")
--OK
--OUTPUT 1 : (Cat "mammal","Cat \"mammal\"")
print $ info (Dolphin $ Cat "mammal")
--NOT OK
--OUTPUT 2 : (Dolphin (Cat "mammal"),"Cat \"mammal\"")
print $ show (Dolphin $ Cat "mammal")
--OUTPUT 3 : "Dolphin (Cat \"mammal\")"
在输出2中,我们知道info
正在对Dolphin
类型的参数进行操作(请参阅元组的第一个元素),但它会打印出"Cat \"mammal\""
的第二个元素元组的元素。但我们知道show
类型的参数上执行的Dolphin
应打印出"Dolphin (Cat \"mammal\")"
(参见输出3)。那么为什么ghci(在输出2中)打印出"(Dolphin (Cat "mammal"),"Cat \"mammal\"")"
时我认为它应该打印出来"(Dolphin (Cat "mammal"),"Dolphin (Cat \"mammal\")")"
?
答案 0 :(得分:3)
具有任何代码的Info
的唯一实例是Cat
的实例,因此元组的第二个元素的唯一可能值是show (a :: Cat)
的结果,它总是"Cat \"...\""
{ {1}}。 Info
的{{1}}实例来自Dolphin
;它完全 GeneralizedNewtypeDeriving
Info
实例的内容。
Cat
的{{1}}实例并非来自Show
,它来自Dolphin
的普通机制。它会像您期望的那样显示GeneralizedNewtypeDeriving
。在第二个示例中,deriving (Show)
实例使用Dolphin
实例show (a :: Dolphin)
Show
来显示(Show a, Show b) => Show (a, b)
类型的元组。
这里令人困惑的一点是print
的{{1}}实例正在返回(Dolphin, String)
类型的元组。 Info
唯一要做的就是在Cat
实例中出现的类型变量的每个地方用(Cat, String)
替换GeneralizedNewtypeDeriving
。这样可以Cat
完全执行Dolphin
所做的事情。