当字符串中有撇号时,Words 会返回错误的输出

Ami*_*vić 4 haskell functional-programming

我正在尝试将字符串拆分为单词列表

split_string :: String -> [Word]

split_string x = words x

“函数式编程很有趣,不是吗?” 应该还给我:

[“功能”,“编程”,“是”,“有趣”,“不是”,“它?”]

但它反而返回给我: ["Functional","Programming","is","Fun,","isn\8217t","it?"]

如何避免撇号问题?如果这是一个愚蠢的问题,我是 Haskell 的新手,所以提前抱歉。

lef*_*out 5

人们普遍误解 Haskell 的Show机制是为了什么。许多初学者认为它应该产生漂亮的可视化,但实际上它的目的是专门生成有效的 Haskell 代码表示

这特别意味着它们不应该包含在您将其复制并粘贴回 Haskell 文件时会导致错误的内容。
例如,考虑字符串you tried to show "something" on the terminal。如果 GHCi 将其显示为

"you tried to show "something" on the terminal"
Run Code Online (Sandbox Code Playgroud)

这会导致解析错误。引号需要转义:

"you tried to show \"something\" on the terminal"
Run Code Online (Sandbox Code Playgroud)

这就是Show String实例生成的表单。

通常,表示不是唯一的。例如

"you tried to show \34something\34 on the terminal"
Run Code Online (Sandbox Code Playgroud)

也可以,符号\34的 ASCII 字符代码在哪里"。这种形式实际上可以用于任何字符:

Prelude> "\72\101\108\108\111\44\32\87\111\114\108\100"
"Hello, World"
Run Code Online (Sandbox Code Playgroud)

当然,对所有字符这样做很愚蠢,但是 Haskell 标准在所有非 ASCII 字符都以转义方式显示的意义上安全地播放:

Prelude> "Amila Be?irovi?"
"Amila Be\269irovi\263"
Run Code Online (Sandbox Code Playgroud)

优点是您可以避免由不兼容的字符编码引入的怪癖——在 2000 年代初期,当网页使用特定于语言的 8 位编码时,这种情况经常发生。现在这应该不再是一个问题了

正如 Willem Van Onsem 所写,你总是可以用 来原始转储一个字符串putStrLn,它不会转义任何东西——尽管这并不直接适用于字符串列表

为了获得更大的灵活性,您可以选择一个Show没有这种行为的不同类,例如从pragmatic-show包中

Prelude> import qualified Text.Show.Pragmatic as SP
Prelude SP> SP.print ["Functional","Programming","is","Fun,","isn’t","it?"]
["Functional","Programming","is","Fun,","isn’t","it?"]
Prelude SP> SP.print "Amila Be?irovi?"
"Amila Be?irovi?"
Run Code Online (Sandbox Code Playgroud)

请注意,这仍然会转义真正不安全的字符:

Prelude SP> SP.print "bla\34blub"
"bla\"blub"
Run Code Online (Sandbox Code Playgroud)