0

How to implement this logic with switch operator instead of large if/else?

   type token =
  | DOT
  | OPEN_BRACKET
  | SYMBOL;

let dot_code = ".".[0] |> Char.code;
let open_bracket_code = "{".[0] |> Char.code;

let char_to_token symbol :token => {
  let code = Char.code symbol;
  let c =
    if (code === dot_code) {
      DOT
    } else if (code === open_bracket_code) {
      OPEN_BRACKET
    } else {
      SYMBOL
    };
  c
};

String.iter
  (
    fun symbol => {
      let c = char_to_token symbol;
      switch c {
      | DOT => print_string " DOT "
      | OPEN_BRACKET => print_string " OPEN_BRACKET "
      | SYMBOL => print_char symbol
      }
    }
  )
  "a.s {";

Or what is the best way to iterate string and detect symbols like . and { ?

tuchk4
  • 2,270
  • 5
  • 21
  • 34

1 Answers1

1

First, instead of ".".[0] |> Char.code, try '.' |> Char.code. Reason/OCaml has character literals. In this case, since it's a single pipe, Char.code '.' is encouraged.

Second, I'd personally use a switch in char_to_token too:

let char_to_token symbol :token =>
  switch symbol {
  | '.' => DOT
  | '{' => OPEN_BRACKET
  | _ => SYMBOL
  };

Which obviates the need for the above let dot_code = ... in the first place. The benefit of using switch, as you might have guessed, is that it's more efficient. See the compiled-to-js code here. Same thing happens for native compilation.

The rest looks good! Btw since you've told me (in discord) that you've just started Reason, I'd say this is pretty simple and keep it this way! When you get more proficient, I sense that you might want a real parser here or try GADT (http://mads-hartmann.com/ocaml/2015/01/05/gadt-ocaml.html).

chenglou
  • 3,640
  • 2
  • 25
  • 33