【问题标题】:Extend a Show instance to a Tuple of any size将 Show 实例扩展到任意大小的元组
【发布时间】:2015-06-03 12:16:19
【问题描述】:

我想用 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 " " ... 在列表元素之间插入内容。但出于许多原因,我希望使用元组而不是列表。

【问题讨论】:

  • 没有。至少不是以一种简单的方式。但是您可以只更改元组的show 实例的输出:rewrite ('(':xs) = replace "," " " $ init xs 其中replace 来自Data.String.Utils
  • 如果你可以使用像(1,('a',"b"))这样的嵌套元组,它应该是直截了当的;)
  • 听起来你在寻找一个漂亮的打印库。看看黑客攻击;有几个不错的(有细微的差别)。

标签: haskell tuples instance


【解决方案1】:

Haskell 绝对没有办法 编写在不同大小的元组上具有多态性的代码。

但鉴于您似乎所做的只是创建Data 的元组(实际上只是Double),我不得不问...为什么不只使用列表?您可以轻松、轻松地处理所有可能大小的列表。

【讨论】:

  • 事实上,我的Data 类型将包含几种类型(Double、Integer、String,...)。我的Data 列表必须连贯且大小固定。如果我使用列表列表,我将不得不执行许多测试来检查这种凝聚力。元组列表将保持简单。
  • @JeanJouX 这种听起来你可以使用this
  • “连贯”是什么意思?
【解决方案2】:

如何为元组编写通用代码

这在语言中直接支持,因为 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,它可能会起作用,但这是一个非常邪恶的扩展,最好假装它根本不存在。

【讨论】:

  • 我喜欢有点邪恶和严重邪恶的区别。
  • 澄清一下:Idris 的元组是否与 Haskell 的列表同构?
  • @ThreeFx,不,他们真的只是一对。在 Idris 中,元组语法是纯糖,the (Nat `Pair` (Char `Pair` String)) (1,('2',"3")) 让你得到(1, '2', "3") : (Nat, Char, String)
  • @dfeuer 你当然是对的,谢谢。我忘记了异构集合。
猜你喜欢
  • 2017-11-29
  • 2023-03-11
  • 2021-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-27
  • 1970-01-01
  • 2018-07-07
相关资源
最近更新 更多