0

I have been learning OCaml and have been trying to write a function that takes in a list of lists of type int, which are representing a matrix. For example: [[1;2;3]; [4;5;6]; [7;8;9]] and in return I want to return a bool value indicating if it is a proper matrix, or not. The way this is decided is if all rows in the matrix have the same amount of elements (like the example shown above)

Thus, I have created the following function:

let rec matrix lst =
  match lst with
  | h::t -> 
    (match h with
    | a ->
      if (List.length a = List.length (matrix t)) then true else false) 

My function type is not what I'm expecting. It should just be

is_matrix : (int list) list -> bool 

or the general equivalent with a'

I'm getting a compile error saying: the variant type list has no constructor true Any idea what's that about?

let rec getlength x =
  match x with
  | [] -> 0
  | a::b -> List.length a + getlength b


let matrix lst =
  match lst with 
  | [] -> true
  | h::t -> if (getlength h = getlength t) then true else false  
11
  • the code you provided does not compile (around the 2nd List.length). Commented Sep 21, 2017 at 14:23
  • @PierreG. Hello Pierre. Yes, I am aware of that, that is the current code I have written, which is not compiling (type error) thus what i'm asking help with Commented Sep 21, 2017 at 14:24
  • Ok - I understood that you managed to get your function compiled but that it signature was not the expected one. Commented Sep 21, 2017 at 14:28
  • No! Sorry for the mixup, my mistake actually Commented Sep 21, 2017 at 14:30
  • 1
    as already mentionned below : since (matrix t) is supposed to be a boolean and not a list, List.length (matrix t) has no meaning... Other point : the second match instruction is useless : when there is a match, then a=h; so keep only the following -> and replace a by h. Commented Sep 21, 2017 at 15:59

3 Answers 3

1

Your original code is wrong because of List.length a = List.length (matrix t) normally matrix t is a boolean, so it's not really clear what does List.length true means.

In your second solution the problem is in h::t -> if (getlength h = getlength t). getlength is of type 'a list list -> int, so you can't call it with type, let say, 'b (type of h) and then with type 'b list (type of t).

But in general I think you are moving in right direction. Simple algorithm may looking like this:

  1. Calculate length of the first element of list,

  2. For each remaining element calculate its length and compare it with result of (1), if they are equal continue, else return false.

  3. Return true if there is no more elements.

This algorithm can be implemented in many different way. I strongly recommend you to do it yourself, but I can't resist to post this simple and elegant solution:

let matrix (h::t) =
    let l = List.length h in
    let rec f = function
        | [] -> true
        | h::t -> if List.length h = l then f t
                  else false in
    f t

Once again, be sure that you fully understand this code before using it.

Sign up to request clarification or add additional context in comments.

Comments

0

The problem is in the following expression:

List.length matrix t

This tries to apply List.length to two arguments: matrix and t. This function only takes one argument (a list), so this reports a type error.

2 Comments

That makes sense! Now however, I'm getting a compile error saying: the variant type list has no constructor true Any idea what's that about?
matrix is expected to return a boolean I guess... So what is the meaning of List.length matrix t or List.length (matrix t) ; that is List.length boolean
0

You need to add the case for [[]] if you want the type system to understand that you're working with lists of lists.

| [[]] -> true

This would then mean you can use List.length on the lists like your originaly wanted.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.