SML Multiple Set Intersection Function - list

I need to write a function in SML that takes an arbitrary number of lists as input and returns the intersection of all the sets given. For example, the function needs to have the following form:
multiSetIntersection([s1,s2,s3,s4]) = (Intersection of s1,s2,s3,s4)
I have been able to write the intersection function that takes in two lists as follows:
fun intersec([], y) = []
| intersec(x::xs, y) =
if memberOf(x,y) then x::intersec(xs,y)
else intersec(xs,y)
But I am unable to "generalize" this function to take in an arbitrary number of lists as input. I have tried the following:
fun multiSetIntersection([]) = []
| multiSetIntersection((x::xs)::y) =
if memberOf(x,y) then x::multiSetIntersection([xs,y])
else multiSetIntersection([xs,y])
But this is giving me some type mismatch errors and will not work properly. Can anybody help me or give me some tips in order to write this function?
Thank you!

Using this intersection function
fun intersect ([], _) = []
| intersect (x::xs, ys) =
if List.exists (fn y => x = y) ys
then x :: intersect (xs, ys)
else intersect (xs, ys)
To do a multiple set intersection, there are 3 cases.
If there are no sets, the intersection is [].
If there is one set xs, the intersection is that set.
If there are more than two sets, the intersection is the intersect of the first set and the intersection of all the remaining sets.
Putting these four cases together we get:
fun intersects [] = []
| intersects [xs] = xs
| intersects (xs::xss) = intersect (xs, intersects xss);;

Related

Custom comparator sort in SML?

I am a bit stuck with this problem in SML / SMLNJ and I would love some guidance.
So I have a problem where I need to make a function called insertSorted, where it takes a number, a comparison statement, and an (assumed sorted) list that it needs to insert into. I'm not sure how to start approaching this so any help would be amazing.
My thought is to split the two lists up where the number would be, insert the number, and then concatenate both lists.
fun insertSorted (x, comp, []) = [x]
| insertSorted (x, comp, a::rest) = ...
Update: I got a bit farther now I just need to know how to debug this, any guidance?
fun insertSorted (x, []) = [x]
| insertSorted (x, y::ys) =
if (x < y)
then x::y::ys
else if (x > y)
then y::x::ys
else y::insertSorted (x, ys);
Update 2: My new goal is to figure out how to merge these two functions into one. Ultimately named insertSorted.
fun insertSorted (x, nil) = [x]
| insertSorted (x,y::ys) = if x<y then x::y::ys else y :: insertSorted (x,ys);
fun insertSorted (x, nil) = [x]
| insertSorted (x,y::ys) = if x>y then y::x::ys else y :: insertSorted (x,ys);
There are three cases:
The list is nil.
You've already covered this. :-)
The list is not nil, and its first element is less than x, so we need to keep searching for where to insert x.
In this case, the result should be the first element, followed by the result of inserting x into the rest of the list.
The list is not nil, and its first element is greater than or equal to x, so we can insert x right here.
In this case, the result should be x, followed by the entire list.
Distinguishing cases #2 and #3 involves if/then/else; implementing case #2 involves recursion.

How to create a list of object by using some sort of filter with a predicate

I'm iterating through a list of nodes in order to create edges between them, however I want to check if the edge between two nodes are not crossing a 'dangerous' place, so I created a function that will work as a predicate to insure I do not create a such an edge. However I don't see how I would be able to properly build my list of edges.
The types manipulated are :
type position = float * float
type node = position
type edge = position * position * float
I have written this, it doesn't work, but this is what I had in mind, I don't know what I could use in OCaml to make it work
let create_edges nodes_list =
let rec create_edges_aux nodes =
match nodes with
| [] -> []
| x::[] -> (x,x,0.) :: []
| x::tl -> List.map (fun x2 -> if (is_safe_edge x x2) then (x,x2,extract_float(dist2 x x2))) tl # create_edges_aux tl
in create_edges_aux nodes_list
The problem is here obviously List.map (fun x2 -> if (is_safe_edge x x2) then (x,x2,extract_float(dist2 x x2))) tl # create_edges_aux tl
The function works perfectly if I do this : List.map (fun x2 -> (x, x2, (extract_float (dist2 x x2)))) tl # create_edges_aux tl but the unsafe edges aren't filtered ...
In the end my problem is that I'm not able to create a list of edges that satisfy the predicate function I coded and the goal is to be able to make that list.
If you have any ideas or solution, thanks.
What you want to do is filtering of the values, which cannot be done with List.map as it always take all the values.
One first option is to first filter the edges with List.filter then map.
If you use OCaml 4.08 or later you can use the dedicated List.filter_map function.
If you are using an older version of OCaml you can also use List.fold_left function to do the mapping and filtering.
In short, List.map can only modify all the values, if you need to filter out some values, it's not the function you need.
It looks to me like you just need an else part in your if.
A code pattern that you see a lot in OCaml is something like this:
let f x =
let x' = if x > 100 then 100 else x in
g x'
When using an if in a functional context, the if always needs an else, because the expression must have a value in both cases. Quite often the else value is the original (unmodified) input value.

Creating an intersection and difference in ML New Jersey

Using the function contains constructed earlier, write a function intersection that takes two list (modeling sets) and returns a list that comes up with the intersection of two sets. So
intersection([1, 2, 3], [1, 3])
would return [1, 3].
Using the function contains constructed earlier, write a function difference which takes two list and returns a list modeling the difference of the first set from the second set (Set A – Set B).
I've created this code contains which is down below, now my goal is to create both an intersection and difference function.
fun contains(x, []) = false
| contains(x, y::rest) =
if x = y
then true
else contains(x, rest);
fun intersection([], y) = []
| intersection(x, y) = if x = y
then [x,y]
else [];;
Trying it:
- intersection([1, 2], [2, 3]);
val it = [] : int list list
As for your contains function, it can be improved slightly:
fun contains(x, []) = false
| contains(x, y::rest) =
x = y orelse contains(x, rest)
That is, if P then true else Q is the same as P orelse Q.
The higher-order standard-library solution is to write
fun contains (x, ys) = List.exists (fn y => x = y) ys
But the former is preferrable if the exercise is to demonstrate understanding of basic recursion.
As for your intersection function, it seems that however you managed to make contains, you are not applying the same principles of list recursion. You compare x = y, but here x and y are lists, not individual elements. Whereas in contains, x is a single value within a list/set, and y is the first element of the list/set y::rest.
So you should probably start to either annotate each argument with a type, or name it in such a way that you're not in doubt about what it's supposed to represent. For intersection the rule is that you only want elements that are members of both lists/sets.
For example:
fun intersection (xs, ys) = ...
Or with types annotated:
fun intersection (xs : ''a list, ys : ''a list) = ...
And you may think that you need to use recursion on lists by pattern matching on the empty/non-empty lists on either xs or ys. I've picked xs here because it happened to be the first argument, but this is arbitrary:
fun intersection ([], ys) = ...
| intersection (x::xs, ys) = ...
Or with types annotated:
fun intersection ([] : ''a list, ys : ''a list) = ...
| intersection (x::xs : ''a list, ys : ''a list) = ...
Then you can ask yourself:
What is the intersection between the empty list/set and ys?
Is x a part of the intersection of x::xs and ys?
What other elements might be part of this intersection (recursively)?

SML - Multiplying Coefficients of Polynomials

I have two lists that contain coefficients for two different polynomials, and I'm looking to write a function that can multiply them together (i.e F-O-I-L).
The function I wrote is not complete, however I was just using it to test my understanding of how it should work.
fun polyMult(nil, nil) = nil
| polyMult(M as x::xs, N as y::ys) =
(x * y)::polyMult(xs, ys);
Am I on the right track?
Also, I have an error message stating uncaught exception Match [nonexhaustive match failure]
What does that mean?
Unfortunately, you are not on the right track. Your function just zips the two lists with multiplication, which is not how F-O-I-L works. By definition of polynomial multiplication, your function should return a polynomial of a higher degree. This should be helpful for you to understand F-O-I-L.
The nonexhaustive match error means that you are not covering all the possible cases for the two lists in your pattern matching. In fact, you are missing the two cases where one of the lists is nil and the other one is not. In terms of your function this would mean the cases where the function has the lists of coefficients from polynomials of different degrees.
If you want to separately handle those two cases you are currently missing, you can go like this:
fun polyMult(M, N) = case (M,N) of
([], []) => []
| ([], y::ys) => ...
| (x::xs, []) => ...
| (x::xs, y::ys) => ...
Of course, replace the dots with your implementation. I hope this helps, good luck.
You need to do this
fun foldL F y nil = y
| foldL F y (x::xr) = foldL F (F(x,y)) xr;
fun polymult(M:real list, nil) = nil
| polymult(nil, N) = nil
| polymult(m::mr, N) = foldL(fn(x,a) => x * a) m N::polymult(mr,N);
thatll do what you want it to.

Haskell Function that Takes A Pair of Values and a List

My homework has been driving me up the wall. I am supposed to write a function called myRepl that takes a pair of values and a list and returns a new list such that each occurrence of the first value of the pair in the list is replaced with the second value.
Example:
ghci> myRepl (2,8) [1,2,3,4]
> [1,8,3,4].
So far I have something like this (but its very rough and not working well at all. I need help with the algorithm:
myRep1 (x,y) (z:zs) =
if null zs then []
else (if x == z then y : myRep1 zs
else myRep1 zs )
I don't know how to create a function that takes a pair of values and a list. I'm not sure what the proper syntax is for that, and I'm not sure how to go about the algorithm.
Any help would be appreciated.
How about something like:
repl (x,y) xs = map (\i -> if i==x then y else i) xs
Explanation
map is a function that takes a function, applies it to each value in the list, and combines all the return values of that function into a new list.
The \i -> notation is a shortcut for writing the full function definition:
-- Look at value i - if it's the same as x, replace it with y, else do nothing
replacerFunc x y i = if x == y then y else i
then we can rewrite the repl function:
repl (x, y) xs = map (replacerFunc x y) xs
I'm afraid the map function you just have to know - it is relatively easy to see how it works. See the docs:
http://www.haskell.org/hoogle/?hoogle=map
How to write this without map? Now, a good rule of thumb is to get the base case of the recursion out of the way first:
myRep1 _ [] = ???
Now you need a special case if the list element is the one you want to replace. I would recommend a guard for this, as it reads much better than if:
myRep1 (x,y) (z:zs)
| x == z = ???
| otherwise = ???
As this is home work, I left a few blanks for you to fill in :-)
myRepl :: Eq a => (a, a) -> [a] -> [a]
myRepl _ [] = []
myRepl (v, r) (x : xs) | x == v = r : myRepl (v, r) xs
| otherwise = x : myRepl (v, r) xs
Untupled arguments, pointfree, in terms of map:
replaceOccs :: Eq a => a -> a -> [a] -> [a]
replaceOccs v r = map (\ x -> if x == v then r else x)