Haskell Show for String的实例是如何编写的?

Haskell Show for String的实例是如何编写的?,haskell,typeclass,Haskell,Typeclass,我有一个关于定义类型类实例的基本问题。我以ShowTypeClass为例,只考虑类中的函数Show。像Bool这样的具体类型的Show实例很简单 instance Show Bool where show x = {function of x here} 但对于字符串,它不是: instance Show String where show x = {function of x here} 产生一个可以理解的错误 Illegal instance declaration for ‘F

我有一个关于定义类型类实例的基本问题。我以ShowTypeClass为例,只考虑类中的函数Show。像Bool这样的具体类型的Show实例很简单

instance Show Bool where
  show x = {function of x here}
但对于字符串,它不是:

instance Show String where
  show x = {function of x here}
产生一个可以理解的错误

Illegal instance declaration for ‘Formatter String’
  (All instance types must be of the form (T t1 ... tn)
   where T is not a synonym.
   Use TypeSynonymInstances if you want to disable this.)
In the instance declaration for ‘Formatter String’
当然,以下情况是不允许的:

instance Show [Char] where
  show x = {function of x here}
我可以定义一个新类型

newtype String2 = String2 String 
instance Formatter String2 where
  format (String2 x) = {function of x here}
但这不允许我做“测试”,就像我在Haskell做的那样


我缺少类型类的哪些基本功能?

Show类型类实际上有三个成员函数,
Show
showsPrec
showList
。在
Show Char
的实例中,
showList
函数被重载以输出引号,并将所有字母挤在一起而不使用分隔符:

发件人:

其中定义为:

showLitString :: String -> ShowS
-- | Same as 'showLitChar', but for strings
-- It converts the string to a string using Haskell escape conventions
-- for non-printable characters. Does not add double-quotes around the
-- whole thing; the caller should do that.
-- The main difference from showLitChar (apart from the fact that the
-- argument is a string not a list) is that we must escape double-quotes
showLitString []         s = s
showLitString ('"' : cs) s = showString "\\\"" (showLitString cs s)
showLitString (c   : cs) s = showLitChar c (showLitString cs s)

因此没有
Show String
实例,只是
Show Char
定义了如何在
[Char]
值上调用
Show

字符串格式是Char实例的一部分,通过showList方法。
showLitString :: String -> ShowS
-- | Same as 'showLitChar', but for strings
-- It converts the string to a string using Haskell escape conventions
-- for non-printable characters. Does not add double-quotes around the
-- whole thing; the caller should do that.
-- The main difference from showLitChar (apart from the fact that the
-- argument is a string not a list) is that we must escape double-quotes
showLitString []         s = s
showLitString ('"' : cs) s = showString "\\\"" (showLitString cs s)
showLitString (c   : cs) s = showLitChar c (showLitString cs s)