我有代码:
data Value = A|Two|Three...Ten|J|Q|K deriving (Eq, Ord, Enum)
instance Show Value where
show A = "A"
show Two = "2"
....
show K = "K"
另一个数据Suite
包含Show
,Hearts
,Spades
和Clubs
的类似Diamonds
个实例。
如果我有
type Card = (Value, Suite)
是否可以创建一个将(A, Spades)
转换为字符串"AS"
的show函数?
答案 0 :(得分:4)
您应为newtype
定义data
(或Card
类型),为其编写Show
个实例。
newtype Card = Card (Value,Suite)
instance Show Card where
show (Card (v,s)) = show v ++ show s
您还可以启用TypeSynonymInstances
并在编写Card
时编写实例。
编辑:我可能还应该提到类型同义词不是处理你的情况的惯用/ Haskell-ish方式。 Card
在语义上与Value
和Suite
对不同,后者可能代表(例如)纸牌游戏中的某些初始条件,而不一定是实际卡片。
答案 1 :(得分:4)
您可能应该定义自己的数据类型,而不是使用(,)
。
data Card = Card Value Suite
instance Show Card where
show (Card v s) = show v ++ show s
答案 2 :(得分:1)
要为ta ype定义实例,您需要使用TypeSynonymInstances
扩展名。在您的情况下,instace Show Card
将等同于instance Show (Card, Suite)
。如果没有FlexibleInstance
,则不允许这样做,因为标准类型类仅允许Show (a,b)
之类的实例。
现在,使用FlexibleInstance
是不够的,因为已经定义了Show (a,b)
并且您的新实例将与默认实例重叠:编译器如何在您的Show (Card, Value)
实例与标准之间进行选择一个Show (a,b)
? (使用类型是不够的,类型就像做文本替换)。要解决重叠实例的问题,您需要使用OverlappingInstance
扩展名:这有点棘手,通常不推荐。