Reputation: 6801
I'm writing a code that can find the median of a list, and I cannot use rec and should use List.fold_left/right. I wrote the following code, which should work.
It finds the length of the list, if it's an odd number like 5, then it sets len1, len2 to 2, 3, if it's an even number like 6, then it sets len1, len2 to 2, 3.
Then for each member in the list I match the number of those elements that are less than it.
However, the following pattern matching always math lessNum elmt to len1 - can someone tell me why it is so?
let median (lst : int list) : float option =
let len = List.length lst in
if lst = [] then None
else
let len1, len2 = (len - 1) / 2, (len + 1) / 2 in
let lessNum a =
List.length (List.find_all (fun n -> n < a) lst) in
let answer = List.fold_left (fun accm elmt ->
match (lessNum elmt) with
| len1 -> accm + elmt
| len2 -> failwith "len2"
| _ -> failwith "other"
) 0 lst in
if len mod 2 = 0
then Some ((float_of_int answer) /. 2.0)
else Some (float_of_int answer)
Upvotes: 2
Views: 115
Reputation: 66823
An identifier appearing in a pattern always matches, and binds the corresponding value to the identifier. Any current value of the identifier doesn't matter at all: the pattern causes a new binding, i.e., it gives a new value to the identifier (just inside the match).
# let a = 3;;
val a : int = 3
# match 5 with a -> a;;
- : int = 5
# a;;
- : int = 3
#
So, your match statement isn't doing what you think it is. You'll probably have to use an if
for that part of your code.
Update
Here's how to use an association list to approximate the function f
in your followup question:
let f x = List.assoc x [(pat1, ans1); (pat2, ans2)]
This will raise a Not_found
exception if x
is not equal to pat1
or pat2
.
(I think your Python code is missing return
.)
Upvotes: 4