Comparing list of floats - ocaml

I wrote a code:
let rec compareVs v1 v2 =
if List.length v1 == 0 then
true
else
((match v1 with [] -> 0. | h::l -> h) == (match v2 with [] -> 0. | h::l -> h)) &&
(compareVs(match v1 with [] -> [] | h::l -> l) (match v2 with [] -> [] | h::l -> l))
And ran it:
# compareVs [0.1;0.1] [0.1;0.1];;
- : bool = false
Can't seem to find the problem. Please help.
EDIT
The problem seams to be with float comparisons:
# 0.1 == 0.1;;
- : bool = false
# 1.0 == 1.0;;
- : bool = false
How else can we compare floats in ocaml?

Use =, not ==.
Floats are reference types in ocaml and == checks reference equality. So 0.1 == 0.1 is false.
Generally, you almost always want to use =, not == to compare two values.
Note that aside from that, your function will return true for two lists of different size. Assuming that's not intended you should only return true when both lists are empty and false when one of them is empty and the other is not.
As a style note, using List.length to check whether a list is empty is usually a bad idea (for one thing it's O(n) even though it can be done in O(1) with pattern matching). Using pattern matching right at the beginning will also clean your code up a bit.
Like this:
let rec compareVs v1 v2 = match v1, v2 with
| [], [] -> true
| [], _
| _, [] -> false
| x::xs, y::ys -> x = y && compareVs xs ys
Oh and if this isn't just an exercise, note that you can just do v1 = v2 and don't actually need to write a function for this.

Sepp2k is correct, but as an additional discussion about comparing floats (which is often dangerous), the following functions have helped me:
This compares two floats with tolerance of epsilon and the syntax would be similar to other float functions. clearly extending >. and others is obvious.
let epsilon = 1.0e-10
let (=.) a b = (abs_float (a-.b)) < epsilon
If you are dealing with many extreme values of floats, you should look at the classify_float function in the pervasives module. I don't recall off the top of my head how NAN values are compared in the = function. You can independently experiment with this if you need to.
I had used this for awhile, but its tolerance was actually way to low for my usage (as in, a very small value for epsilon as above). This does not take into account what, NAN - NAN does. So, this might not be useful.
let (=.) a b = match classify_float ( a -. b ) with
| FP_infinite | FP_nan | FP_normal -> false
| FP_subnormal | FP_zero -> true

Related

How do you see if adjacent elements repeat in a list? (SML)

SML is a challenging language for me to learn. I'm trying to find a way to screen an undetermined list and return a boolean based on whether two elements adjacent on a list are the same value or not. What I've tried and think is close to correct is below.
fun repeatE nil = false
| repeatE (first::last) = first = last orelse repeatsE(last);
Obviously, this results in an error. I based my answer on this code, which tells me if a value is an element in the list.
fun member (e, nil) = false
| member (e, first::last) = e = first orelse member(e, last);
Why does the first one not work, but the last one does? It tells me that the operator and the operand don't agree, and maybe I'm thick-headed, but I don't quite understand why they don't?
Thank you in advance!
first=last tries to compare the first element of a list with the tail of that list, and you can only compare things of the same (comparable) type.
The working code works because it doesn't try to compare a list element to an entire list.
You need to compare the first element to the second element, and you need to handle the case of a singleton list.
Something like this:
fun repeats nil = false
| repeats (first::rest) = case rest of
(x::xs) => first = x orelse repeats rest
| _ => false
or
fun repeats nil = false
| repeats (first::rest) = not (null rest)
andalso (first = (hd rest) orelse repeats rest)
It's actually possible to use as to clean up #molbdnilo's answer a fair bit.
Ask yourself: An empty list is false, but so is a list with a single element, right?
fun repeats([]) = false
| repeats([_]) = false
Now, we need to match a list with at least two elements, and compare those. If they're not equal, we'll check everything but the first element.
fun repeats([]) = false
| repeats([_]) = false
| repeats(a::b::tail) =
a = b orelse repeats(b::tail)
But we don't need to use b::tail.
fun repeats([]) = false
| repeats([_]) = false
| repeats(a::(tail as b::_)) =
a = b orelse repeats(tail)
If we want, we can recognize that the empty list and the single element list are just the "other" when the last pattern doesn't match, and we'll rewrite it to reflect that.
fun repeats(a::(tail as b::_)) =
a = b orelse repeats(tail)
| repeats(_) = false

How to find the opposite of a number in a list of list in OCaml?

I'm trying to find the opposite of a number in a list of list. I want to iterate through every element of the list of list, and check if the opposite of this element is in the list of list.
This is what I've done so far:
let rec findOpposite l =
match l with
| [] -> false
| f::x::ll -> if (List.mem (-x) f = false && List.mem (-x) ll = false) then true else findOpposite ll;;
I naively assumed 'f' was representing all the previous elements of the list...
I also explored this solution: flatten the list, to make it a bit more simple. But now I'm kinda lost.
What's expected here is to iterate through every element of the list, check if its opposite is in there, if so -> true, otherwise continue until we reach the end.
Thanks.
If this isn't an assignment, I can give one possible solution. If I understand correctly, you want to know if a set of integers is closed under negation. You can calculate the set, then negate the set, then see if the two sets are equal.
module ISet =
Set.Make(struct type t = int let compare = compare end)
let get_set ll =
List.fold_left
(List.fold_left (fun is i -> ISet.add i is))
ISet.empty
ll
let negate_set is = ISet.map (fun i -> -i) is
let closed_set is = ISet.equal is (negate_set is)
You can try it out like this:
# closed_set (get_set [[1;2]; [-2;-2]; [3;-3;-1]]);;
- : bool = true
# closed_set (get_set [[1;2]; [-2;-2]; [3;-3]]);;
- : bool = false

Why use null function instead of == [] to check for empty list in Haskell?

I am reading through the "Starting Out" chapter of Learn You a Haskell for Great Good!. It says:
null checks if a list is empty. If it is, it returns True, otherwise it returns False. Use this function instead of xs == [] (if you have a list called xs)
I tried in ghci:
xs = [] -- and then,
xs == []
null xs
Both of them are True.
I wonder what's the difference.
Should I use the null function instead of == [] and why?
You should use null. In most cases it doesn't matter, but it is a good habit to get into anyway, because occasionally you may want to check if a list of non-comparable things is empty. Here is a short, crisp example showing this difference:
> null [id]
False
> [id] == []
<interactive>:1:1: error:
• No instance for (Eq (a0 -> a0)) arising from a use of ‘==’
(maybe you haven't applied a function to enough arguments?)
• In the expression: [id] == []
In an equation for ‘it’: it = [id] == []
There is a difference. In order to use x == [], the type of the elements of the list should be a member of the Eq typeclass. Indeed, checking the equality of two lists is defined by the instance declaration:
instance Eq a => Eq [a] where
[] == [] = True
(x:xs) == (y:ys) = x == y && xs == ys
_ == _ = False
That means that you can not use x == [] if x is for example a list of IO Ints.
null :: [a] -> Bool on the other hand, uses pattern matching. This is implemented as:
null :: [a] -> Bool
null [] = True
null (_:_) = False
So regardless what type the elements of the list are, it will always typecheck.
In addition to the good answers given so far, null actually has type
null :: Foldable t => t a -> Bool
I don't know if you've gotten to typeclasses in LYAH, but the short of it is that null can be used not just for lists, but for any data structure that implements null.
This is to say that using null on a Map or a Set is valid, too.
> null Map.empty
True
> null (Map.singleton 1)
False
> null Set.empty
True
> null (Set.singleton 1)
False
> null []
True
> null [1]
False
I don't think it's especially common to write functions that need to be this general, but it doesn't hurt to default to writing more general code.
A side note
In many cases, you'll end up wanting to use a function like null to do conditional behavior on a list (or other data structure). If you already know that your input is a specific data structure, it's more elegant to just pattern match on its empty case.
Compare
myMap :: (a -> b) -> [a] -> [b]
myMap f xs
| null xs = []
myMap f (x:xs) = f x : myMap f xs
to
myMap' :: (a -> b) -> [a] -> [b]
myMap' f [] = []
myMap' f (x:xs) = f x : myMap' f xs
In general, you should try to prefer pattern matching if it makes sense.
Also a simple function that filter all empty list would fail:
withoutEmpty = filter (== [])
and that would be:
withoutEmpty = filter null
notice that:
withoutEmpty ls = filter (==[]) ls
will work just fine, but the important point is that in some cases like the other one could fail.
Also look at #cole answer, it complements all the answers here, the typeclass Foldable has the null function there to be implemented:
To see more info of Foldable here

Why do i get syntax error at end problem with pattern matching

I have to make a function that takes list a list and returns list of pairs of first and last element,2nd and 2nd last and so forth It doesn't matter if the list has even or odd number of elements because if its odd i will just ignore the middle element.The idea i have is that make a new rec fun that takes old list and its revers as input i think i finished the code but i get Syntax error for ;;
let lip l =
if [] then []
else let l1=l l2=List.rev l in
let rec lp l1 l2 = match l1,l2 with
| [],[] ->[]
| [],h2::t2->[]
| h1::_,h2::_ ->
if (List.length l -2) >= 0 then [(h1,h2)]# lp(List.tl l1) t2
else [] ;;
There are quite a few errors in your code.
I think the specific error you're seeing is caused by the fact that there is no in after let rec lp ....
Every let that's not at the top level of a module needs to be followed by in. One way to think of it is that it's a way of declaring a local variable for use in the expression that appears after in. But you need to have the in expr.
Another way to look at it is that you're defining a function named lp but you're not calling it anywhere.
As #lambda.xy.x points out, you can't say if [] then ... because [] isn't of type bool. And you can't say let x = e1 y = e2 in .... The correct form for this is let x = e1 in let y = e2 in ...
(Or you can write let x, y = e1, e2 in ..., which looks nicer for defining two similar variables to two similar values.)
The following code should at least compile:
let lip list1 =
if list1 = [] then []
else
let list2=List.rev list1 in
let rec lp l1 l2 = match l1,l2 with
| [], [] ->[]
| [], _::_->[]
| h1::_::_, h2::t2 -> (* l1 length >= 2*)
(h1,h2) :: lp(List.tl l1) t2
| h1::_,h2::t2 -> (* l1 length = 1 *)
[]
in
[]
I have made the following changes:
renamed the arguments of lip to make clear they are different from the arguments of lp
removed the alias let l1 = l
changed the if condition to a term of type boolean -- there's not much to compare, so I assume you are checking list1
replaced the list length condition by a pattern match against two heads
the else path is the second match - it might be better to rewrite that one to | [h1, _] -> ...
the definition of lp needs to be followed with the actual body of lip - to make it compile, we just return [] at the moment but you probably would like something else there
As #Jeffrey Scofield already mentioned, you are not using lp in your code. It could help if you added a comment that explains what you'd like to achieve and what the intended role of lp is.

Error trying to "print" list in Haskell

I have the following problem: given a max(max) apacity, and given a list of values(listOfValues) i need to return a list with values from the listOfValues. The sum of the elements must be <= max and i need to prioritize the higher values.
Example: typing solvingProblem 103 [15, 20, 5, 45, 34] i must get: [45, 45, 5, 5]
To solve the problem i create the following code:
solvingProblem max [] = 0
solvingProblem max listOfValues | max == 0 = 0
| otherwise = createList max listOfValues []
createList max [] result = -1
createList max listOfValues result | smaller listOfValues > max = -1
| higher listOfValues > max = createList max (remove (higher listOfValues) listOfValues) result
| otherwise = createList (max - higher listOfValues) listOfValues (insert (higher listOfValues) result)
higher [a] = a
higher (a:b:x) | a > b = higher (a:x)
| otherwise = higher (b:x)
smaller [a] = a
smaller (a:b:x) | a < b = smaller (a:x)
| otherwise = smaller (b:x)
remove x [] = []
remove x (h:t) | x == h = remove x t
| otherwise = h : remove x t
insert x (h:t) = x : h : t
In the two lines where i'll returning "-1" should be the parameter "result", but if i change "-1" to "result" the code don't load on ghci.
Can someone help me?
Thank you and sorry for my bad english.
If I may begin with a bit of a side note, some of your functions already exist in Haskell (now that I come to think of it you might have written them for an exercise, but just in case it wouldn't be the case, let's discuss that): your higher is maximum, your smaller is minimum and your insert is just (:), beacause like you write it yourself insert x list = x:list. Note that your version will fail if you give it the empty list because the pattern matching is non-exhaustive. Also you could write remove in terms of filter: remove x list = filter (== x) list.
Now why doesn't your code load properly? ghci tells you:
• Non type-variable argument in the constraint: Num [a]
(Use FlexibleContexts to permit this)
• When checking the inferred type
solvingProblem :: forall a.
(Ord a, Num [a], Num a) =>
a -> [a] -> [a]
Which I agree is pretty cryptic, but what it's saying is that the return type of solvingProblem is a list of a and for some reason it is also an instance of the Num type class. The reason why it says it's an instance of Num is because one of the return value of solvingProblem is 0 which is a number, which is a bit odd because it is also a list. Changing the 0 with [] makes the code compile and work (if you change insert with (:) otherwise you get the non-exhaustive pattern matching I was talking about earlier).
λ> solvingProblem 103 [15,20, 5, 45, 34]
[5,5,45,45]
it :: (Ord t, Num t) => [t]
The problem is with the last guard clause in createList.
The type you intended for createList seems to be:
createList :: Int -> [Int] -> Int -> Int
but if you look at the last guard clause you have:
| otherwise = createList (max - ...) listOfValues (insert ...)
^^^^^^^^^^^ ^^^^^^^^^^^^ ^^^^^^^^^^^^
Int [Int] [Int]
Even though GHC is very good at inferring types, always adding
type signatures to your code is a good way of catching these kinds
of errors early.