将Show实例扩展为任何大小的元组

时间:2015-06-03 12:16:20

标签: haskell tuples instance

我想用Haskell创建一种新类型的数据并创建相关的Show实例。我需要使用另一个分隔符,创建元组Show实例。

我实现了这段代码(使用{-# LANGUAGE FlexibleInstances #-} pragma):

newtype Data = Data Double

instance Show Data where
  show (Data dat) = show dat

instance Show (Data,Data) where
  show (Data d1,Data d2) = show d1++" "++show d2

instance Show (Data,Data,Data) where
  show (Data d1,Data d2,Data d3) = show d1++" "++show d2++" "++show d3

是否可以自动将Show实例扩展为任意大小的元组而无需手动创建实例?

注意:我知道我可以使用concat $ intersperse " " ...在列表元素之间插入内容。但由于种种原因,我希望使用元组而不是列表。

2 个答案:

答案 0 :(得分:4)

Haskell绝对无法编写代码,这些代码具有不同大小的元组的多态性。

但考虑到你所做的一切都是创建Data的元组(实际上只是Double),我不得不问......为什么不使用列表?您可以轻松,轻松地处理所有可能大小的列表。

答案 1 :(得分:3)

如何编写元组的通用代码

这是直接支持该语言,因为Haskell中的元组是全部或全部。在Idris中,这很容易,因为(a,b,c)实际上意味着(a,(b,c))。 Haskell的懒惰会使这种表示效率低下,而且无论如何Haskell只是对元组的概念有不同的概念。但是,您可以使用generics来编写那种代码!我保证会很痛苦。

为什么你要做的事情是个坏主意

最大的问题不是你正在尝试制作通用的元组代码。最大的问题是您的Show个实例与通常的实例重叠。基础库已导出

instance (Show a, Show b) => Show (a, b)
instance (Show a, Show b, Show c) => Show (a,b,c)

等。在确定实例是否重叠时,您必须只查看=>右侧。因此,即使您的Data不在Show,您也会遇到问题。 Haskell坚持在查看箭头左侧之前承诺选择实例。默认情况下,如果它不能唯一地解析实例,则会通过抱怨重叠实例来实现此目的。如果你OverlappingInstances可能让它正常工作,但这不是一个很好的用例,对于那个有点邪恶的扩展。如果你使用IncoherentInstances,它可能会起作用,但这是一个如此大规模的邪恶扩展,假装根本不存在它会好得多。