How do you append a char to a string in OCaml?

2019-04-06 09:02发布

It seems as if there is no function in the standard library of type char -> string -> string, which insert a char in front of (or at the end of) a string. There are workarounds, e.g. by using String.make or String.blit. Is there an elegant way to do this?

3条回答
女痞
2楼-- · 2019-04-06 09:19

String.make and String.blit is a good way to do so, but they seem to be imperative. Personally I prefer to make infix functions using Char.escaped and string concatenation:

let (^$) c s = s ^ Char.escaped c (* append *)
let ($^) c s = Char.escaped c ^ s (* prepend *)
查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-04-06 09:19

I made a comparison of the efficiency of different approaches:

  1. I wrote a simple test:

    let append_escaped s c = s ^ Char.escaped c
    let append_make    s c = s ^ String.make 1 c
    let append_sprintf s c = Printf.sprintf "%s%c" s c
    
    let _ =
      let s = "some text" in
      let c = 'a' in
      for i = 1 to 100000000 do
        let _ = append_(*escaped|make|sprintf*) s c in ()
      done
    
  2. I compiled it natively (Intel Core 2 Duo).

  3. I ran the test three times for each option, timing it with time, and calculating the mean real time elapsed.

Here are the results:

  1. s ^ String.make 1 c: 7.75s (100%)

  2. s ^ Char.escaped c: 8.30s (107%)

  3. Printf.sprintf "%s%c" s c: 68.57s (885%)

查看更多
做个烂人
4楼-- · 2019-04-06 09:27

The code from @pad is what I would use, because I like to treat strings as immutable if possible. But I wouldn't use Char.escaped; it's specialized for when you want the OCaml lexical representation of a character. So here's what you get if you make that change:

let prefix_char s c = String.make 1 c ^ s

let suffix_char s c = s ^ String.make 1 c

Update

In the years since this question was asked, OCaml has changed so that strings are immutable. Excellent.

查看更多
登录 后发表回答