将 Show 实例扩展为任意大小的 Tuple
Extend a Show instance to a Tuple of any size
我想用 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 " " ...
在列表元素之间插入内容。但出于多种原因,我希望使用元组而不是列表。
Haskell 绝对无法 编写在不同大小的元组上具有多态性的代码。
但是鉴于您似乎所做的只是创建 Data
的元组(实际上只是 Double
),我不得不问...为什么不直接使用列表?您可以轻松、轻松地处理所有可能大小的列表。
如何为元组编写通用代码
这 不 语言直接支持,因为 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
,它可能会起作用,但这是一个非常邪恶的扩展,最好假装它根本不存在。
我想用 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 " " ...
在列表元素之间插入内容。但出于多种原因,我希望使用元组而不是列表。
Haskell 绝对无法 编写在不同大小的元组上具有多态性的代码。
但是鉴于您似乎所做的只是创建 Data
的元组(实际上只是 Double
),我不得不问...为什么不直接使用列表?您可以轻松、轻松地处理所有可能大小的列表。
如何为元组编写通用代码
这 不 语言直接支持,因为 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
,它可能会起作用,但这是一个非常邪恶的扩展,最好假装它根本不存在。