LowRez
LowRez

Reputation: 125

Write a multiline function in ocaml

I'm having trouble understanding how to write functions in ocaml as I've only written recursive functions that don't require multiple lines separated by a ;.

I'm trying to create a function that given a int number n returns a matrix full of zeroes and just ones in the diagonal, so an identity matrix of size n.
I'm new to functional programming and ocaml so I was wodering if it was possible to write this in a imperative way. For example in Java I'd write:

public int[][] identity(int size) {
    int[][] matrix;
    matrix = new int[size][size];
    //fill the matrix with zeroes
    for( int i=0; i<size; i++){
        for( int j=0; j<size; j++){
            matrix[i][j] = 0;
        }
    }
    //diagonal values at 1
    for (int i=0; i<size; i++){
        matrix[i][i] = 1;
    }
    return matrix;
}

How can I achieve this in ocaml?

Upvotes: 3

Views: 3740

Answers (2)

Goswin von Brederlow
Goswin von Brederlow

Reputation: 12322

You can do it basically the same way in OCaml like this:

let identity size =
  let m = Array.make_matrix size size 0 in
  for i = 0 to size - 1 do
    m.(i).(i) <- 1;
  done;
  m

The difference in OCaml is that you have to create a matrix filled with something (0 in this case). So the first loop to set entries to 0 disappears since Array.make_matrix does that internally. There is no way around initializing it. And then you change the diagonal to 1.

The alternative is to initialize the matrix with the correct values in the first place. You can do that too like this:

let identity size =
  Array.init
    size
    (fun x ->
       Array.init
         size
         (fun y -> if x = y then 1 else 0))

Upvotes: 1

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66818

You can write OCaml code in an imperative way, yes. OCaml has matrices (represented as arrays of arrays), matrices are mutable, and it has a for statement. So you can write code that looks very similar to what you wrote in Java.

It seems a shame to learn OCaml only to write imperative code, however!

Here are some code fragments that you can put together:

# let m = Array.make_matrix 3 3 0;;
val m : int array array = [|[|0; 0; 0|]; [|0; 0; 0|]; [|0; 0; 0|]|]

# m.(1).(1) <- 1;;
- : unit = ()

# m;;
- : int array array = [|[|0; 0; 0|]; [|0; 1; 0|]; [|0; 0; 0|]|]

# for i = 0 to 9 do Printf.printf " %d" i done;;
 0 1 2 3 4 5 6 7 8 9- : unit = ()

There is nothing special about a multi-line function in OCaml. Here is a function that does three things. You can write it on one line or on many lines:

let f x =
    Printf.printf "I will now write the value of x\n";
    Printf.printf "Here is the value of x: %d\n" x;
    Printf.printf "I just wrote the value of x\n"

In OCaml, ; is used to separate expressions that should be evaluated in order. I.e., there's no ; after the last expression.

Upvotes: 1

Related Questions