I'm wondering how can I build a function in Ocaml that uses List.fold_left to find out if an element exists in a list.
Example:
exists 3 [1;2;3;4;5]
=> true
The type of this function is: a -> bool -> 'a list -> bool
My idea how to do it is as follows:
let exists k l = List.fold_left( fun a x-> a=x) k l
but obviously is wrong. Any suggestion how to do it?
let exists k l =
List.fold_left (fun b x -> b || x = k) false l
Two comments on #tonio's answer:
Use || instead of superfluous if ... then true else ....
Use structural equality (=) instead of reference equality (==) for comparing values.
Moreover, exists is available in List module. The built-in function is more efficient since it doesn't have to go through the whole list every time.
You should use something like
let exists k l =
List.fold_left(
fun a x -> if x == k then true else a)
false l
;;
You have an initial value of false, and pass it while iterating over the list. Once the searched element is found, set the value to true, and pass it along. If the element in the list is not what you search, pass the value you had as input: it is either the initial false, or true if the element you search for has already been found.
after the hints taken by the answers i could be able to improve it more.
Here is my solution
let exists' f l =List.fold_left(fun a b-> f b || a ) false l;;
Like this, this function is more abstract and can be used for any predicate f.
Related
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
I need to implement a method to return common elements in two lists as part of an assignment problem:
My idea was to remove duplicates in both lists, concatenate them and return elements that are repeated in the resulting list. I want to define a Boolean function that check for each elements in the list if they appear more than once. My idea was to use List.fold_left with a specific element b in the list and use acc to keep track of the number of times it appears in the list. However, I have an error here:
I have another idea that involves sorting the lists first, But the list could be of any type, hence comparison has to be implemented for new types as well. Or can I just use < to compare any type of values?
Here are the codes that I have so far.
let rec remove (b : 'a) (l : 'a list)=
match l with
| [] -> []
| w::e -> if w=b then remove b e
else w::(remove b e)
let rec removeduplicates (l:'a list)=
match l with
| [] -> []
| w::e -> w::(removeduplicates(remove w e))
let removeduppair (l : 'a list * 'a list)=
let (l1,l2) = l in
(removeduplicates l1, removeduplicates l2)
This expression has a type error:
if x = b then acc + 1
The problem is that doesn't have an else part. In other words, it doesn't say what you want the value to be when x is not equal to b.
You can fix this just by adding an else part.
A little more detail: OCaml allows you to leave off the else part, but only if the then part has unit type. In such a case, the value when the test is false will be the same as when it is true, namely () (the only value of unit type).
The question might sound confusing but basically
I want to make a function that takes in a list and another function. Now going through that list I want to get the count of elements that return true when inputted into this parameter function. Im new to sml so my mistake was that I intended to add a count to a helper function and increment that alongside If statements but I learned soon enough that you can't really increment values in ml. Can someone please explain the more sml way of doing this? I'm just looking to understand what I'm missing.
fun helper f nil counter = false
| helper f xs 1 = true
| helper f (x::xs) counter =
if (f x) = true then
counter = counter + 1
else
counter = counter + 0
fun numberExisting f alist = (helper f alist 0);
The function should not return a boolean, so neither should your helper.
"Incrementing" is also a concept that doesn't make much sense in a language without mutation.
(counter = counter + 1is a comparison that will never be true.)
You don't need the helper, but you need to think recursively:
If the list is empty, the result is zero.
If the list is not empty:
If the given predicate is true for the head of the list, the result is one more than the result of recursing over the tail of the list.
If the given predicate is false for the head of the list, the result is the same as the result of recursing over the tail of the list.
In ML:
fun numberExisting _ [] = 0
| numberExisting f (x::xs) = if f x
then 1 + numberExisting f xs
else numberExisting f xs
Not easy way to explain this, but I will try. I think i'm confusing my method with some C, but here it goes:
I want to check if a list is complete, like this:
main> check 1 [1,3,4,5]
False
main> check 1 [1,2,3,4]
True
It's a finite list, and the list doesn't have to be ordered. But inside the list there most be the number that misses to be True. In the first case it's the number 2.
This is my version, but it doesn't even compile.
check :: Eq a => a -> [a] -> Bool
check n [] = False
check n x | n/=(maximum x) = elem n x && check (n+1) x
| otherwise = False
So if I understand this correctly, you want to check to see that all the elements in a list form a sequence without gaps when sorted. Here's one way:
noGaps :: (Enum a, Ord a) => [a] -> Bool
noGaps xs = all (`elem` xs) [minimum xs .. maximum xs]
[minimum xs .. maximum xs] creates a sequential list of all values from the lowest to the highest value. Then you just check that they are all elements of the original list.
Your function doesn't compile because your type constraints are greater than what you declare them as. You say that a only needs to be an instance of Eq - but then you add something to it, which requires it to be an instance of Num. The way you use the function also doesn't make sense with the signature you declared - check [1,2,3,4] is a Bool in your example, but in the code you gave it would be Eq a => [[a]] -> Bool (if it compiled in the first place).
Do you only need this to work with integers? If not, give some example as to what "complete" means in that case. If yes, then do they always start with 1?
Here's another take on the problem, which uses a function that works on sorted lists, and use it with a sorted input.
The following will check that the provided list of n Int contains all values from 1 to n:
check :: (Num a, Ord a) => [a] -> Bool
import List
check l = check_ 1 (sort l)
where check_ n [] = True
check_ n [x] = n == x
check_ n (x:y:xs) = (x+1)==y && check_ (n+1) (y:xs)
Note the use of List.sort to prepare the list for the real check implemented in check_.
I've come across 2 confusing problems in SML and was hoping someone could help me out:
The first is a function which takes an element and a list and decides whether that element exists in the list or not, here is the code I've attempted to write:
fun member (e,L) = foldl (fn(a,b) => if (e = b) then true else false) false L;
But I get bool * 'a list --> bool but what I need is ''a * ''a list --> bool
As for the second, it also requires an element and a list but returns a list of elements less than the passed one. I'm not sure whether this should be done via map or foldr/foldl.
Any suggestions?
Thanks in advance :)
Regarding the first question, in fn (a, b) => ... a is the next element and b is the accumulator. Since you compare e with b, e is infered to have type bool. You should compare e with a, and never override b when it becomes true:
fun exists (e, L) =
foldl (fn (a, b) => e = a orelse b) false L
For the second question, you can use foldr/foldl to do so. It's similar to the first example; you start with empty list as the accumulator and prepend an element to it whenever that element is smaller than a threshold.
As a tradeoff, foldr gives you the right order but it isn't tail-recursive. On the other hand, foldl is tail-recursive but gives resulting lists in a reverse order.
to see if an element is in list or not try this:
fun elementExist(e, nil) = false
| elementExist(e, x::xs) = if e = x orelse elementExist(e, xs) then true else false;
for the second one to remove the existing element from the list:
fun elFromList(e, nil) = []
| elFromList(e, x::xs) = if e = x then elFromList(e, xs) else x::elFromList(e, xs);
Good Luck!!