采用以下定义:
p = "abc"
q = ['a', 'b', 'c']
Run Code Online (Sandbox Code Playgroud)
由于字符串是字符列表,因此表达式的p == q计算结果为True。那就好了。
当我让 GHCi 计算表达式时p,它显示了值"abc"。这是预期的,因为p类型为String。(在 GHCi 中,命令:type p显示p :: String。)但是当我让 GHCi 计算表达式 时q,它也显示 value "abc"。这实际上是出乎意料的,因为q是 类型[Char],而不是String。(在 GHCi 中,该命令:type q显示q :: [Char],而不是。)因此,尽管和q :: String的类型相等,但我希望显示为字符列表,而不是字符串。String[Char]q
在我看来,表达式['a', 'b', 'c'] :: String应该生成字符串 value "abc",而表达式"abc" :: [Char]应该生成列表 value ['a', 'b', 'c']。但似乎并非如此。我认为这很奇怪。那么我如何才能真正将p和显示q为字符列表 ( ['a', 'b', 'c']) 而不是字符串 ( "abc") 呢?如果这不可能,那为什么不可能呢?(如果字符串是字符列表,我是否也应该能够将其显示为字符列表?)
String并且[Char]是完全相同的类型。类型Show类包含一个“技巧”,可以使用与其他列表不同的语法来打印该类型。
如果您需要常规的类似列表的输出,您可以使用自定义的Char类似类型来绕过该异常。请注意,在打印结果之前,您需要转换为该类型。
{-# LANGUAGE TypeApplications #-}
import Data.Coerce
newtype C = C Char
instance Show C where
show (C c) = show c
main :: IO ()
main = do
print $ map C ['a', 'b', 'c']
-- output: ['a', 'b', 'c']
print $ coerce @[Char] @[C] ['a', 'b', 'c']
-- output: ['a', 'b', 'c']
Run Code Online (Sandbox Code Playgroud)
该map C方法比较简单,但效率较低。该方法使用安全强制来进行从到 的coerce零成本转换。[Char][C]