是否可以为类型别名声明类型类实例?

时间:2017-03-19 14:24:15

标签: haskell

我有代码:

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包含ShowHeartsSpadesClubs的类似Diamonds个实例。

如果我有

type Card = (Value, Suite)

是否可以创建一个将(A, Spades)转换为字符串"AS"的show函数?

3 个答案:

答案 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在语义上与ValueSuite对不同,后者可能代表(例如)纸牌游戏中的某些初始条件,而不一定是实际卡片。

答案 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扩展名:这有点棘手,通常不推荐。

相关问题