我有以下功能(来自Real World Ocaml书),可以很好地与核心库一起使用:
let upcase_first_entry line =
match String.split ~on:',' line with
| [] -> assert false
| first :: rest -> String.concat ~sep: "," (String.uppercase first :: rest);;
所以当我评估时:
upcase_first_entry ("one,two");;
我得到:
- : string = "ONE,two"
根据我对函数的理解,首先将字符串转换为字符串列表,然后应用大写函数,最后将输出转换回字符串。 所以我尝试了以下功能:
List.map ~f:(fun (first :: last) -> (String.uppercase first :: last)) ["one","two"];;
我直接将列表传递给函数。但是我收到以下错误:
Error: This pattern matches values of type 'a list
but a pattern was expected which matches values of type
string * string
有人可以指导我为什么会引发错误吗?
答案 0 :(得分:1)
直接在解释器中输入参数["one", "two"]
会得到
- : (string * string) list = [("one", "two")]
即,字符串对列表不是字符串列表。您可能打算键入["one"; "two"]
,即string list
。在OCaml中,即使没有给出括号,,
也会用于创建对和其他元组。
下一个问题是List.map
将函数应用于列表的每个元素并创建一个新列表。在这种情况下,它期望将f
映射到某物的string
。但是您的匿名函数将字符串列表映射到字符串列表(string list -> string list
)。
在这种情况下,最简单的解决方案可能是不使用List.map
,而只是将函数应用于参数。
(fun (first :: last) -> (String.uppercase first :: last)) ["one";"two"]
结果警告表明缺少一个案例。实际上,没有为空列表定义匿名函数。对于给定的参数而言,这无关紧要,但是通常,最好定义应该发生的情况,这样可以避免警告:
(function (first :: last) -> (String.uppercase first :: last) | [] -> []) ["one";"two"]