我想用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 " " ...
在列表元素之间插入内容。但由于种种原因,我希望使用元组而不是列表。
答案 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
,它可能会起作用,但这是一个如此大规模的邪恶扩展,假装根本不存在它会好得多。