James Monger
James Monger

Reputation: 10665

Totalling a variable in OCaml

I have a program which loops through a string and prints out the dir of each character.

I want to total these dir values up into a single discrete value, which I can print.

Here is my current code:

let word = "(())";;

let dir = function
  | '(' -> 1
  | ')' -> -1
  | _ -> 0;;

let z =
  (String.iter (fun (c: char) ->
    let d = dir c in
      Printf.printf "%d is the direction of %c\n" d c
  ) word);;

At the moment, this prints out the following:

1 is the direction of (
1 is the direction of (
-1 is the direction of )
-1 is the direction of )

Instead of printing these out, I would like it to sum the 4 values (1, 1, -1, -1) and print out:

The overall direction is 0

How can I achieve this in OCaml?

Upvotes: 1

Views: 120

Answers (3)

ivg
ivg

Reputation: 35210

Loops in OCaml as well as other functional programming languages are usually expressed using recursive functions. Here is a possible implementation:

let count_parens str =
  let n = String.length str in
  let rec loop s i =
    if i < n then match str.[i] with
      | '(' -> loop (s + 1) (i + 1)
      | ')' -> loop (s - 1) (i + 1)
      | _ -> loop s (i + 1)
    else s in
  loop 0 0

Or, using your dir function:

let count_parens str =
  let n = String.length str in
  let rec loop s i =
    if i < n then loop (s + dir str.[i]) (i + 1)
    else s in
  loop 0 0

A reification of a loop is a fold function. Unfortunately there is no String.fold function in the OCaml standard library. But you can use a Core standard library produces by Janestreet. With fold function this loop can be expressed more concise:

open Core_kernel.Std  

let count_parens str =
  String.fold str ~init:0 ~f:(fun s c -> s + dir c)

Upvotes: 1

Pierre G.
Pierre G.

Reputation: 4431

Using a reference :

let z =
  let counter = ref 0 in (String.iter (fun (c: char) ->
    counter := (!counter + dir c)
  ) word); !counter;; 

Upvotes: 0

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66818

The short answer is that you should use fold instead of iter. Since there's no fold in the standard String library, you might have to write your own.

A slightly longer answer is that you probably want to write a recursive function that tracks a cumulative sum as one of its parameters.

Upvotes: 1

Related Questions