如何在 SML 中编写多行字符串?
How to write multiline strings in SML?
如何编写跨多行的字符串?
我试过像许多其他语言一样在末尾使用续行符 \
,但它似乎不起作用。以下:
val s = "line1\
line2";
生成错误:
/tmp/...:1: error: unexpected character l in \ ... \
/tmp/...:1: error: no matching quote found on this line
不使用任何续行符会产生类似的错误:
val s = "line1
line2";
多行字符串的正确写法是什么?
你也必须在下一行的开头加上反斜杠:
print "this is\
\ a string on\
\ 3 lines\n";
如果您正在使用 SML/NJ 并且您不太关心可移植性,则有一个鲜为人知的功能不仅可以为您提供多行字符串,还可以为您提供变量插值。 SML/NJ 支持可扩展的引用机制,这里有更详细的描述:https://www.smlnj.org/doc/quote.html
现在,为了解决您的问题,我们可以定义以下 引号解析器。我称它为 s
是为了与 Scala 的 s"..."
语法相提并论,这将在稍后变得更加清晰。
val s : string SMLofNJ.frag list -> string =
let
fun fold (SMLofNJ.QUOTE s, acc) = acc ^ s
| fold (SMLofNJ.ANTIQUOTE s, acc) = acc ^ s
in
List.foldl fold ""
end
请注意,它使用 SMLofNJ
结构来访问特定于编译器的数据类型和值(frag
、QUOTE
和 ANTIQUOTE
)。
我们现在可以像这样使用上面的代码(确保您使用的是命令行选项 -Cparser.quotations=true
):
$ sml -Cparser.quotations=true
- val a = "var";
val a = "var" : string
-
- val b = `this is a raw quotation using ^a`;
val b = [QUOTE "this is a raw quotation using ",ANTIQUOTE "var",QUOTE ""] :
string SMLofNJ.frag list
-
- val c = s`this is an interpolated string: ^a`;
val c = "this is an interpolated string: var" : string
-
- print c;
this is an interpolated string: varval it = () : unit
-
- val d = s`this
… is
… a
… multiline string: ^a`;
val d = "this\nis\na\nmultiline string: var" : string
-
- print d;
this
is
a
multiline string: varval it = () : unit
如您所见,将引号与非常简单的自定义解析器(s
函数)结合使用,我们可以获得 SML/NJ.
中的多行内插字符串
在我的个人图书馆中,我以更结构化的方式定义了它:
structure Strings =
struct
structure Interpolated =
struct
local
open SMLofNJ
in
(**
* Support for multiline, interpolated strings.
*
* NB: requires SML/NJ quotations: sml -Cparser.quotations=true.
*
* ```sml
* - open Strings.Interpolated;
* - val v = "val";
* val v = "val" : string
* - val j = s`{
* = "key": "^v"
* = }`;
* val j = "{\n \"key\": \"val\"\n}" : string
* ```
*)
val s : string frag list -> string =
let
fun fold (QUOTE s, acc) = acc ^ s
| fold (ANTIQUOTE s, acc) = acc ^ s
in
List.foldl fold ""
end
end
end
end
如何编写跨多行的字符串?
我试过像许多其他语言一样在末尾使用续行符 \
,但它似乎不起作用。以下:
val s = "line1\
line2";
生成错误:
/tmp/...:1: error: unexpected character l in \ ... \
/tmp/...:1: error: no matching quote found on this line
不使用任何续行符会产生类似的错误:
val s = "line1
line2";
多行字符串的正确写法是什么?
你也必须在下一行的开头加上反斜杠:
print "this is\
\ a string on\
\ 3 lines\n";
如果您正在使用 SML/NJ 并且您不太关心可移植性,则有一个鲜为人知的功能不仅可以为您提供多行字符串,还可以为您提供变量插值。 SML/NJ 支持可扩展的引用机制,这里有更详细的描述:https://www.smlnj.org/doc/quote.html
现在,为了解决您的问题,我们可以定义以下 引号解析器。我称它为 s
是为了与 Scala 的 s"..."
语法相提并论,这将在稍后变得更加清晰。
val s : string SMLofNJ.frag list -> string =
let
fun fold (SMLofNJ.QUOTE s, acc) = acc ^ s
| fold (SMLofNJ.ANTIQUOTE s, acc) = acc ^ s
in
List.foldl fold ""
end
请注意,它使用 SMLofNJ
结构来访问特定于编译器的数据类型和值(frag
、QUOTE
和 ANTIQUOTE
)。
我们现在可以像这样使用上面的代码(确保您使用的是命令行选项 -Cparser.quotations=true
):
$ sml -Cparser.quotations=true
- val a = "var";
val a = "var" : string
-
- val b = `this is a raw quotation using ^a`;
val b = [QUOTE "this is a raw quotation using ",ANTIQUOTE "var",QUOTE ""] :
string SMLofNJ.frag list
-
- val c = s`this is an interpolated string: ^a`;
val c = "this is an interpolated string: var" : string
-
- print c;
this is an interpolated string: varval it = () : unit
-
- val d = s`this
… is
… a
… multiline string: ^a`;
val d = "this\nis\na\nmultiline string: var" : string
-
- print d;
this
is
a
multiline string: varval it = () : unit
如您所见,将引号与非常简单的自定义解析器(s
函数)结合使用,我们可以获得 SML/NJ.
在我的个人图书馆中,我以更结构化的方式定义了它:
structure Strings =
struct
structure Interpolated =
struct
local
open SMLofNJ
in
(**
* Support for multiline, interpolated strings.
*
* NB: requires SML/NJ quotations: sml -Cparser.quotations=true.
*
* ```sml
* - open Strings.Interpolated;
* - val v = "val";
* val v = "val" : string
* - val j = s`{
* = "key": "^v"
* = }`;
* val j = "{\n \"key\": \"val\"\n}" : string
* ```
*)
val s : string frag list -> string =
let
fun fold (QUOTE s, acc) = acc ^ s
| fold (ANTIQUOTE s, acc) = acc ^ s
in
List.foldl fold ""
end
end
end
end