OCaml函数参数模式匹配字符串

lka*_*htz 10 ocaml

我试图传入一个字符串来获得一个反向字符串.为什么我不能这样做:

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',它们分别将字符串转换为字符列表,反之亦然. 以下是它们的示例实现.


Mat*_*aun 5

正如Kristopher Micinski 所解释的,您无法像处理列表那样使用模式匹配来分解字符串。

\n\n

但您可以使用 将它们转换为列表explode。这是reverse使用模式匹配的函数explode及其对应函数implode

\n\n
let rec reverse str =\n  match explode str with\n    [] -> ""\n    | h::t -> reverse (implode t) ^ string_of_char h\n
Run Code Online (Sandbox Code Playgroud)\n\n

像这样使用它:

\n\n
let () =\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)\n
Run Code Online (Sandbox Code Playgroud)\n\n

这表明它适用于单字节字符,但不适用于多字节字符。

\n\n

这里有explode一个implode辅助方法:

\n\n
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)\n
Run Code Online (Sandbox Code Playgroud)\n