Haskell 元组可以有一个特殊的Show实例吗?
我正在使用所谓的标记,这些标记是带有字符串和标记的元组,我希望能够以以下格式呈现在屏幕上:Haskell 元组可以有一个特殊的Show实例吗?,haskell,Haskell,我正在使用所谓的标记,这些标记是带有字符串和标记的元组,我希望能够以以下格式呈现在屏幕上:[tag:VALUE]我不能这样做,因为我做得不对。以下是设置: type Token value tag = ([value], tag) data Tag = Whitespace | Alpha | Digit | Punctuation | Terminal instance Show Tag where show Alpha = "A" show Whitespace = "W"
[tag:VALUE]
我不能这样做,因为我做得不对。以下是设置:
type Token value tag = ([value], tag)
data Tag = Whitespace | Alpha | Digit | Punctuation | Terminal
instance Show Tag where
show Alpha = "A"
show Whitespace = "W"
show Digit = "D"
show Punctuation = "P"
show Terminal = "|"
type TextToken = Token Char Tag
instance Show TextToken where
show (values, tag) = "[" ++ show tag ++ ": " ++ values ++ "]"
在编译时崩溃:
Illegal instance declaration for `Show TextToken'
(All instance types must be of the form (T t1 ... tn)
where T is not a synonym.
Use -XTypeSynonymInstances if you want to disable this.)
In the instance declaration for `Show TextToken'
然后,我尝试用以下内容替换该实例:
instance Show ([Char], Tag) where
show (values, tag) = "[" ++ show tag ++ ": " ++ values ++ "]"
又遇到了同样的问题:
Illegal instance declaration for `Show ([Char], Tag)'
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
Use -XFlexibleInstances if you want to disable this.)
In the instance declaration for `Show ([Char], Tag)'
有什么方法可以让它工作吗?您需要使用新类型
newtype Tag a b = Tag (a, b)
instance (Show a, Show b) => Show (Tag a b) where
show (Tag (a, b)) = "[" ++ show a ++ ": " ++ show b ++ "]"
您同时遇到了几个实例解析问题
{-#语言类型同义词实例#-}
pragma,则无法在实例定义中使用type
同义词。。。即使他们非常清楚。启用它很好,它根本不是Haskell 98{-#LANGUAGE FlexibleInstances}
pragma将允许这些OK机会([Char],Tag)
已经有了一个Show
实例,多态的实例Show(a,b)
带有a~[Char]
和b~ Tag
。这意味着您将遇到OverlappingInstances
警告{-#LANGUAGE OverlappingInstances#-}
来禁用此功能,但由于它可能会导致您自己和使用您的代码的其他人出现非常奇怪的运行时行为,因此非常不鼓励使用它
通常,如果试图将实例声明“专门化”为特定类型,则需要不存在一般情况
newtype Tup a b = Tup (a, b)
instance Show (Tup Int Int) where
show (Tup tup) = show tup
instance Show (Tup String Int) where
show (Tup (s, int)) = s ++ ": " ++ show int
>>> show ("foo", 3)
foo: 3
>>> show (2, 3)
(2, 3)
>>> show ("foo", "bar")
No instance for...
您真正需要决定的事情是,您是否希望为不同种类的
令牌使用不同的实例。如果需要,则使用newtype
(或者一些人建议的编译器选项)。如果没有,则将Token
adata
,并在genericToken
类型上定义实例
要制作newtype
包装器,请执行以下操作:
newtype TextToken = TextToken (Token Char Tag)
然后为包装器声明Show
实例:
instance Show TextToken where
对你来说,我还是建议你改变一下
type Token value tag = ([value], tag)
到
因为你有一个记录类型,所以你最好把它显式化。作为一个旁注,如果你还不熟悉的话,你可以看一看。经验丰富的Haskell程序员的建议是避免覆盖默认的Show
实例show
是调试的主要工具之一:您应该能够show
a数据结构,然后将其复制并粘贴到ghci
中进行进一步调试。您会注意到所有标准库都遵循此格式。如果您想要漂亮的打印,最好定义自己的函数。
data Token value tag = Token [value] tag