4

I have this function for reversing strings in ocaml however it says that I have my types wrong. I am unsure as to why or what I can do :(

Any tips on debugging would also be greatly appreciated!

  28 let reverse s =
  29   let rec helper i =
  30     if i >= String.length s then "" else (helper (i+1))^(s.[i])
  31   in
  32     helper 0

Error: This expression has type char but an expression was expected of type string

Thank you

3 Answers3

9

Your implementation does not have the expected (linear) time and space complexity: it is quadratic in both time and space, so it is hardly a correct implementation of the requested feature.

String concatenation sa^sb allocates a new string of size length sa + length sb, and fills it with the two strings; this means that both its time and space complexity are linear in the sum of the lengths. When you iterate this operation once per character, you get an algorithm of quadratic complexity (the total size of memory allocated, and total number of copies, will be 1+2+3+....+n).

To correctly implement this algorithm, you could either:

  • allocate a string of the expected size, and mutate it in place with the content of the input string, reversed

  • create a string list made of reversed size-one strings, then use String.concat to concatenate all of them at once (which allocates the result and copies the strings only once)

  • use the Buffer module which is meant to accumulate characters or strings iteratively without exhibiting a quadratic behavior (it uses a dynamic resizing policy that makes addition of a char amortized constant time)

The first approach is both the simplest and the fastest, but the other two will get more interesting in more complex application where you want to concatenate strings, but it's less straightforward to know in one step what the final result will be.

gasche
  • 31,259
  • 3
  • 78
  • 100
4

The error message is pretty clear, I think. The expression s.[i] represents a character (the ith character of the string). But the ^ operator requires strings as its arguments.

To get past the problem you can use String.make 1 s.[i]. This expression gives a 1-character string containing the single character s.[i].

Handling strings recursively in OCaml isn't as nice as it could be, because there's no nice way to destructure a string (break it into parts). The equivalent code to reverse a list looks a lot prettier. For what it's worth :-)

Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108
1

You can also use 3rd party libraries to do so. http://batteries.forge.ocamlcore.org/ already implements a function for reversing strings

Alex
  • 19
  • 2