我试图传入一个字符串来获得一个反向字符串.为什么我不能这样做:
let rec reverse x =
match x with
| "" -> ""
| e ^ s -> (reverse s) ^ e;;
Run Code Online (Sandbox Code Playgroud)
编译器说它是语法错误.我不能^用来破坏参数吗?
Kri*_*ski 18
原因是字符串不像列表那样表示为数据类型.因此,虽然cons(::)是构造函数,但^ 不是.相反,字符串表示为较低级别类型而没有递归定义(如列表所示).有一种方法可以将字符串作为字符列表进行匹配,使用来自SML的函数(可以在OCaml中编写),称为'explode'和'implode',它们分别将字符串转换为字符列表,反之亦然. 以下是它们的示例实现.
正如Kristopher Micinski 所解释的,您无法像处理列表那样使用模式匹配来分解字符串。
\n\n但您可以使用 将它们转换为列表explode。这是reverse使用模式匹配的函数explode及其对应函数implode:
let rec reverse str =\n match explode str with\n [] -> ""\n | h::t -> reverse (implode t) ^ string_of_char h\nRun Code Online (Sandbox Code Playgroud)\n\n像这样使用它:
\n\nlet () =\n let text = "Stack Overflow \xe2\x99\xa5 OCaml" in\n Printf.printf "Regular: %s\\n" text;\n Printf.printf "Reversed: %s\\n" (reverse text)\nRun Code Online (Sandbox Code Playgroud)\n\n这表明它适用于单字节字符,但不适用于多字节字符。
\n\n这里有explode一个implode辅助方法:
let string_of_char c = String.make 1 c\n\n(* Converts a string to a list of chars *)\nlet explode str =\n let rec explode_inner cur_index chars = \n if cur_index < String.length str then\n let new_char = str.[cur_index] in\n explode_inner (cur_index + 1) (chars @ [new_char])\n else chars in\n explode_inner 0 []\n\n(* Converts a list of chars to a string *)\nlet rec implode chars =\n match chars with\n [] -> ""\n | h::t -> string_of_char h ^ (implode t)\nRun Code Online (Sandbox Code Playgroud)\n