在 String 上映射 (char -> int)

Map (char -> int) over String

我正在使用 Janestreet 的核心,我基本上想做 String.map str (Char.to_int),但是 String.map 要求函数是 (char -> char) 并且 returns 是一个字符串(不是根据需要列出)。我知道的替代方法是使用 for 循环并制作一个列表,但这不是很 FPish。是否有一张地图接受一个字符串和一个 (char -> 'a) 和 returns 一个 'a 列表?

我在 Core 的 String 模块扩展中看到一个名为 to_list_rev 的函数。它将字符串转换为反向的字符列表。所以,你可以这样做:

List.rev_map Char.to_int (String.to_list_rev s)

更新

看来在Core中,String也是一个Container。 Container 的 link 在文档中不起作用,但我认为这意味着有一个 to_list 函数,使用起来感觉更自然。

所以即使你不想走这条路,这段代码看起来也比上面的更整洁:

List.map Char.to_int (String.to_list s)

像 Jeff 建议的那样写我自己的。应该是相当有效的。

let rec str_map_helper str f acc ind = 
    if ind = -1
      then acc
      else str_map_helper str f ((f str.[ind])::acc) (ind - 1);;

let string_map str f =
  str_map_helper str f [] ((String.length str) - 1);;

虽然这应该作为嵌套函数来完成。

所有地图功能 return 相同的容器,但具有不同的元素。最简单的解决方案是:

  String.to_list str |> List.map ~f:Char.to_int

这个还不错,很常用的成语。当然,您可以使用 rev_map 来加快速度:

 String.to_list_rev str |> List.rev_map ~f:Char.to_int

还有一个更麻烦的选择是在使用 List.init 函数展开字符串的同时构建一个新列表:

 let to_codes str = 
   List.init (String.length str) ~f:(fun n ->
     Char.to_int str.[n])