If I have a list [1;2;3;4;5;6] and I want to return a list of the odd indices [2;4;6], could I do this with List.map and some function? I'm having difficulty figuring this out.
What List.map does is return a function (call it f say) of each of the elements of the list. For each element x of the input list, it returns f x in the resulting list. Hence, the returned list is always the same length as the one it is passed.
Since you want a shorter list, you can't use List.map.
As #UnholySheep says, you could use List.filteri. It's specifically intended for returning only some of the elements of the list based on their position in the list.
I have some prolog code below, which takes a list of integers, and returns me the Max element of said list. My issue is that I'm not quite sure how theList = [H|_] portion of the code works.
I understand that H gets assigned the head value of the list, but the variable List below is what? How does prologue know to take the tail and assign it to List when given the following snippet of code List = [H|_]
To me List could either be H or it could be _ (the tail)... but logically it has to be _ (the tail) or the function below would not work.
max(List,Max) :-
List = [H|_],
accMax(List,H,Max).
Example of code : http://www.learnprolognow.org/lpnpage.php?pagetype=html&pageid=lpn-htmlse21
I am reading Bratko's Prolog: Programming for Artificial Intelligence. The easiest way for me to understand lists is visualising them as binary trees, which goes well. However, I am confused about the empty list []. It seems to me that it has two meanings.
When part of a list or enumeration, it is seen as an actual (empty) list element (because somewhere in the tree it is part of some Head), e.g. [a, []]
When it is the only item inside a Tail, it isn’t an element it literally is nothing, e.g. [a|[]]
My issue is that I do not see the logic behind 2. Why is it required for lists to have this possible ‘nothingness’ as a final tail? Simply because the trees have to be binary? Or is there another reason? (In other words, why is [] counted as an element in 1. but it isn't when it is in a Tail in 2?) Also, are there cases where the final (rightmost, deepest) final node of a tree is not ‘nothing’?
In other words, why is [] counted as an element in 1. but it isn't when it is in a Tail in 2?
Those are two different things. Lists in Prolog are (degenerate) binary trees, but also very much like a singly linked list in a language that has pointers, say C.
In C, you would have a struct with two members: the value, and a pointer to the next list element. Importantly, when the pointer to next points to a sentinel, this is the end of the list.
In Prolog, you have a functor with arity 2: ./2 that holds the value in the first argument, and the rest of the list in the second:
.(a, Rest)
The sentinel for a list in Prolog is the special []. This is not a list, it is the empty list! Traditionally, it is an atom, or a functor with arity 0, if you wish.
In your question:
[a, []] is actually .(a, .([], []))
[a|[]] is actually .(a, [])
which is why:
?- length([a,[]], N).
N = 2.
This is now a list with two elements, the first element is a, the second element is the empty list [].
?- [a|[]] = [a].
true.
This is a list with a single element, a. The [] at the tail just closes the list.
Question: what kind of list is .([], [])?
Also, are there cases where the final (rightmost, deepest) final node of a tree is not ‘nothing’?
Yes, you can leave a free variable there; then, you have a "hole" at the end of the list that you can fill later. Like this:
?- A = [a, a|Tail], % partial list with two 'a's and the Tail
B = [b,b], % proper list
Tail = B. % the tail of A is now B
A = [a, a, b, b], % we appended A and B without traversing A
Tail = B, B = [b, b].
You can also make circular lists, for example, a list with infinitely many x in it would be:
?- Xs = [x|Xs].
Xs = [x|Xs].
Is this useful? I don't know for sure. You could for example get a list that repeats a, b, c with a length of 7 like this:
?- ABCs = [a,b,c|ABCs], % a list that repeats "a, b, c" forever
length(L, 7), % a proper list of length 7
append(L, _, ABCs). % L is the first 7 elements of ABCs
ABCs = [a, b, c|ABCs],
L = [a, b, c, a, b, c, a].
In R at least many functions "recycle" shorter vectors, so this might be a valid use case.
See this answer for a discussion on difference lists, which is what A and Rest from the last example are usually called.
See this answer for implementation of a queue using difference lists.
Your confusion comes from the fact that lists are printed (and read) according to a special human-friendly format. Thus:
[a, b, c, d]
... is syntactic sugar for .(a, .(b, .(c, .(d, [])))).
The . predicate represents two values: the item stored in a list and a sublist. When [] is present in the data argument, it is printed as data.
In other words, this:
[[], []]
... is syntactic sugar for .([], .([], [])).
The last [] is not printed because in that context it does not need to. It is only used to mark the end of current list. Other [] are lists stored in the main list.
I understand that but I don't quite get why there is such a need for that final empty list.
The final empty list is a convention. It could be written empty or nil (like Lisp), but in Prolog this is denoted by the [] atom.
Note that in prolog, you can leave the sublist part uninstantiated, like in:
[a | T]
which is the same as:
.(a, T)
Those are known as difference lists.
Your understanding of 1. and 2. is correct -- where by "nothing" you mean, element-wise. Yes, an empty list has nothing (i.e. no elements) inside it.
The logic behind having a special sentinel value SENTINEL = [] to mark the end of a cons-cells chain, as in [1,2,3] = [1,2|[3]] = [1,2,3|SENTINEL] = .(1,.(2,.(3,SENTINEL))), as opposed to some ad-hoc encoding, like .(1,.(2,3)) = [1,2|3], is types consistency. We want the first field of a cons cell (or, in Prolog, the first argument of a . functored term) to always be treated as "a list's element", and the second -- as "a list". That's why [] in [1, []] counts as a list's element (as it appears as a 1st argument of a .-functored compound term), while the [] in [1 | []] does not (as it appears as a 2nd argument of such term).
Yes, the trees have to be binary -- i.e. the functor . as used to encode lists is binary -- and so what should we put there in the final node's tail field, that would signal to us that it is in fact the final node of the chain? It must be something, consistent and easily testable. And it must also represent the empty list, []. So it's only logical to use the representation of an empty list to represent the empty tail of a list.
And yes, having a non-[] final "tail" is perfectly valid, like in [1,2|3], which is a perfectly valid Prolog term -- it just isn't a representation of a list {1 2 3}, as understood by the rest of Prolog's built-ins.
I'm pretty new to ocaml and I'm having a hard time with this func
I know what it does but not HOW! With a given list, it returns the minimum value of the list and the rest of the list as a pair.
sepmin [2;1;3;4] == (1,[2;3;4])
val sepmin : 'a list -> 'a * 'a list
# let rec sepmin = function
[h] -> h, []
|h::t -> let h1, t1 = sepmin t in
min h h1, (max h h1)::t1;;
Could you guys help me out with the recursive part t.t
First, it is applied to the list's tail recursively. Say, it returns h1 and t1 that are the minimum of the tail and all the other elements of the tail. Next, this element, h, is compared against h1. If it is less than h1, then the pair (h, h1::t1) returned; otherwise the pair (h1, h::t1) is returned. Since the function is called recursively, then probably one of these pairs is returned to the previous recursion point (and its first element is again compared against that point's list head). As far as I can see, the function does not care much about the original order of the elements, i.e. for the list [1; 4; 2; 5; 6] it should return (1, [2; 4; 5; 6]), 2 and 4 are reordered in the result.
A good way to think about recursion is to take it in two pieces. First, what does the function do when the input is trivial? Second (this is the tricky part), assuming the function works for small inputs, how does it transform a bigger intput into a smaller one and use the answer for the smaller case to calculate the correct result for the bigger case.
The trivial case for this function is a list of one element. The answer is obvious in that case.
For a longer list, you can use your recursive power to get the correct answer for the tail of the list (which is a shorter list, hence the recursion will work by assumption). Once you know the answer for the tail of the list, you can construct the correct answer for the full list: the max of the head of the list and the answer for the tail is the overall maximum. You need to add the smaller of these two values back to the list.
I have a SML problem. I need to write a SML function to merge two lists and returns a list of distinct elements.
For example:
- merge [1,2,3,4,5] [4,5,6,7,8];
val it = [1,2,3,4,5,6,7,8] : int list
-merge ["a", "a"] nil;
val it = ["a"] : string list
I only can create a function to merge two lists but cannot remove distinct elements.
- fun merge list1 list2 = list1#list2;
val merge = fn : 'a list -> 'a list -> 'a list
- merge [1,2,3] [3,4,5];
val it = [1,2,3,3,4,5] : int list
How to write a function to merge two lists and remove distinct elements?
Thanks
You'll need two functions---a function that deletes elements, and another function that deletes duplicate elements. The delete function would take argument (item,lst), and delete all the elements in lst that are equal to item.
delete(item,lst) = ...
Next step would be to strip duplicate elements. This function takes your list as an argument. You'll have to use delete function delete items recursively, except for the unique element.
if null hd(lst) then []
else hd(lst)::strip_duplicates(delete(hd(lst),tl(lst)))
I believe you have not told us the entire truth about your problem. It seems that if the lists you wish to merge are sorted, you can compare the first element in each list and put the smallest one in the resulting list. This way the merged list will also be sorted.
The trick here is to realize that while you compare them, if they are equal, you don't actually need to include both in the result, while if they are not equal, you need to include them in the right order.