Concurrent Clean : 汎用クォート関数

というユーティリティ関数を思いついたので、作ってみた。

//quote quote_char escape_char bare_string -> quoted_string
quote :: !Char !Char !String -> String
quote q e s0 # s1 = createArray (2 + newSize 0 0) '\0'
             = copyQuote s1
  where
    l0 = size s0
    newSize p l
        | p >= l0           = l
        | c == q || c == e  = newSize (inc p) (l + 2)
                            = newSize (inc p) (inc l)
      where
        c = s0.[p]
    copyQuote s1
        # (l1, s1) = usize s1
          s1 = update s1 0 q
          s1 = update s1 (l1 - 1) q
        = copyEscape 0 1 s1
      where
        copyEscape p0 p1 s1
            | p0 >= l0          = s1
            | c == q || c == e  # s1 = update s1 p1 e
                                  p1 = inc p1
                                  s1 = update s1 p1 c
                                = copyEscape (inc p0) (inc p1) s1
                                # s1 = update s1 p1 c
                                = copyEscape (inc p0) (inc p1) s1
          where
            c = s0.[p0]

d_quote :== quote '"' '\\'
s_quote :== quote '\'' '\''

動作確認

Start = (d_quote "aa\"bb\\cc\'dd"
        ,s_quote "aa\"bb\\cc\'dd"
        )

結果

(""aa\"bb\\cc'dd"","'aa"bb\cc''dd'")

まずまず便利そうだ。