【问题标题】:Representing strings with embedded quotes in Haskell在 Haskell 中用嵌入引号表示字符串
【发布时间】:2018-03-15 11:00:55
【问题描述】:

在自然语言中,引号内有引号是很常见的,例如:

(1)“这句话不是‘句’”

(2) “‘S’在语言 L iff S 中为真”

(2) 实际上对于任何 Tarski 的真值定义都很重要(Tarski 认为,(2) 的每个实例的真值对于真值定义的材料充分性都是必要的)。

其他例子出现在悖论研究中;众所周知,在Quine's paradox 中,我们被引导考虑(3):

(3) ““''在其引用之前产生错误'的陈述在其引用之前产生错误'是错误的”

我对如何在 Haskell 中实现引用中的引用感兴趣。我想知道的是,在 Haskell 中,通过适当的技术技巧,我们可以如何将 (1)-(3) 表示为上面写的以及它们将出现在书中(即,不以任何方式进行拼写修改),没有收到错误消息。

对 (3) 的简单类型搜索,:t ("The statement "'yields falsehood when preceded by its quotation' yields falsehood when preceded by its quotation" is false") 产生(没有双关语!)

<interactive>:1:18: error:
• Syntax error on 'yields
  Perhaps you intended to use TemplateHaskell or TemplateHaskellQuotes
• In the Template Haskell quotation 'yields

【问题讨论】:

  • 你只需要转义引用,所以"The statement \"'yields falsehood when preceded by its quotation' yields falsehood when preceded by its quotation\" is false"
  • 它不是运算符。我认为你解释字符串有点像普通的 Haskell 代码。这是一个字符串文字。字符串文字对一些无法立即添加的字符进行转义:如引号,还有换行符、制表符、unicode 等。
  • @user65526:您可能在字符串的representation 上混淆了strings。事实上,如果我们写"foo \"bar\" qux"。我们编写了一个 包含 没有反斜杠的字符串,它不包含外引号。如果你打印那个字符串,你会得到foo "bar" qux。关键是字符串文字的 表示 与字符串包含的内容不同。
  • @user65526 stackoverflow.com/questions/19288652/… - 不要对字符串使用 print :) 那么你就不会得到前导/尾随“
  • @user65526 试试putStrLn "foo \"bar\" qux";将字符串中实际包含的字符呈现给终端。只需在 GHCI 提示符下键入 "foo \"bar\" qux" 即可使用 show 来呈现它,这是为了向您显示字符串的表示形式为 Haskell 语法(因此它必须使用反斜杠来转义引号)。 print 在内部也使用 show

标签: string haskell


【解决方案1】:

此答案将主要重复 cmets(以及您自己的答案)中所说的内容,但会进行一些可能有用的详细说明。

在接下来的内容中,我将滥用键盘输入格式,如 case,当我想谈论一个字符串的真实情况时。您可能将“原样”理解为内存中的某个字节序列或更柏拉图式的东西——随意选择您最喜欢的本体。重要的是,如果我想在 Haskell 程序中引用 case ,我需要某种方式来指定我真的在谈论一个字符串,因为 Haskell 源代码实际上是一个字符串以某种方式解释——特别是在这种解释中,case 将被视为引入案例陈述的关键字。 Haskell语法采用的解决方案是用双引号引入字符串字面量,这样"case"就代表case

这一切都很好,但是这句话不是“句子”呢?问题是 Haskell 语法没收了字符 " 等字符,赋予它特殊的含义,这意味着 "This sentence is not a "sentence"" 实际上并不代表 This sentence is not a "sentence" kbd>(更确切地说,它表示这句话不是一个,就像一个函数一样,应用于一个名为sentence的变量和一个空字符串——这几乎总是无意义的)。这个问题的解决方案正在没收 \ 以便将其用作 转义字符,当在字符串文字中使用时,指示以下字符应按字面意思理解,而不是按照通常的方式Haskell 语法中的作用(这不是 \ 用作转义字符的唯一方式,但我们不要陷入细节困境)。既然如此,这句话不是“句子” ""This sentence is not a \"sentence\"" 为代表,万事如意。

在 cmets 中经过长时间的讨论后,以上所有内容可能都非常明显。不过,关于putStrLnshowprint,还有一些有趣的事情要补充。从putStrLn 开始,它的作用可以抽象地描述为在屏幕上绘图,如果你不关心Haskell 语法的普通约束,它看起来很像你将如何表示一个字符串。 putStrLn 和假设的 cartoonifyStrLn 之间没有根本区别,它会在你的桌面上绘制一个粉红色的 Comic Sans 字符串,或者甚至是 seeStrLn,它会直接在你的视网膜中植入字符串的视觉印象。关键是putStrLn "This sentence is not a \"sentence\"" 以一种Haskell 完全外部的方式表示这句话不是“句子”。幸运的是,这个事实是由类型系统表达的:

GHCi> -- Actually a string.
GHCi> :t "This sentence is not a \"sentence\""
"This sentence is not a \"sentence\"" :: [Char]
GHCi> -- Note how there won't be any mention of String (or [Char]).
GHCi> :t putStrLn "This sentence is not a \"sentence\""
putStrLn "This sentence is not a \"sentence\"" :: IO ()

类型中带有IO 的值代表部分或全部在Haskell 之外的事物。 IO 可以参考和使用这些东西,而不会忘记关于它们的这一重要事实。

show 函数产生字符串——或者更准确地说,String——Haskell 值的表示

GHCi> show 99
"99"
GHCi> show (Just 99)
"Just 99"

然而,这是对show 所做工作的不完整描述。它产生的String 应该以字符串文字的形式表示它根据 Haskell 语法给出的值的有效表示。这就是为什么showing a String 会生成一个带有额外引号的字符串...

GHCi> show "case"
"\"case\""

...更不用说所有额外的反斜杠了:

GHCi> show "This sentence is not a \"sentence\""
"\"This sentence is not a \\\"sentence\\\"\""

至于print,它只是show,后跟putStrLn,所以它往往符合您对大多数类型的期望......

GHCi> print 99
99
GHCi> print (Just 99)
Just 99

...但不适用于Strings——在他们的情况下,您应该只使用putStrLn

GHCi> print "This sentence is not a \"sentence\""
"This sentence is not a \"sentence\""

P.S.:关于技术细节的额外阅读可能很有趣:How to convert Unicode Escape Sequence to Unicode String in HaskellSemantics of show w.r.t. escape characters

P.P.S.:我欢迎批评我在这个答案中引用的用法。

【讨论】:

    【解决方案2】:

    正如最初在问题下方的评论中暗示的那样,但当时我并不清楚(尽管对其他人来说可能完全显而易见),有一种表示 (1)-(3 ) 上面使用 \ 和 putStrLn。我们只需要使用以下代码:

    putStrLn "This sentence is not a \"sentence\" "
    This sentence is not a "sentence" 
    
    putStrLn "\"S\" is true in language L iff S"
    "S" is true in language L iff S
    
    putStrLn "The statement \"'yields falsehood when preceded by its quotation' 
    yields falsehood when preceded by its quotation\" is false"
    The statement "'yields falsehood when preceded by its quotation' yields 
    falsehood when preceded by its quotation" is false
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-08
      • 1970-01-01
      • 2018-05-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多