Removing the first instance of x from a list - list

I am new to Haskell and have been trying to pick up the basics.
Assume I have the following list y:
3:3:2:1:9:7:3:[]
I am trying to find a way to delete the first occurrence of 3 in list y. Is this possible using simple list comprehension?
What I tried (this method deletes all instances from a list):
deleteFirst _ [] = []
deleteFirst a (b:bc) | a == b = deleteFirst a bc
| otherwise = b : deleteFirst a bc

No, it's not possible using a list comprehension. In a list comprehension you make a decision which element to keep based on that element only. In your example, you want to treat the first 3 you encounter differently than other 3s (because you only want to remove the first one), so the decision does not depend on the element alone. So a list comprehension won't work.
Your attempt using a recursive function is already pretty close, except that, as you said, it removes all instances. Why does it remove all instances? Because after you removed the first one, you call deleteFirst again on the rest of the list, which will remove the next instance and so on. To fix this, just do not call deleteFirst again after removing the first instance. So just use bc instead of deleteFirst a bc in that case.

as other already mentioned list comprehension is not an appropriate solution to this task (difficult to terminate the execution at one step).
You've almost written the correct solution, just in the case of equality with the matched value you had to terminate the computation by returning the rest of list without the matched element:
deleteFirst _ [] = []
deleteFirst a (b:bc) | a == b = bc
| otherwise = b : deleteFirst a bc
> print $ deleteFirst 3 (3:3:2:1:9:7:3:[])
> [3,2,1,9,7,3]

I don’t believe it is possible to do this with list comprehension (at least not in in any idiomatic way).
Your deleteFirst works almost. All you need to change to fix is is to stop deleting after the first match, i.e. replace deleteFirst a bc in the first clause by bc.

sepp2k's remarks about list comprehensions are an important thing to understand; list operations like map, filter, foldr and so on treat all list items uniformly, and the important thing to understand about them is what information is available at each step, and how each step's result is combined with those of other steps.
But the aspect I want to stress is that I think you should really be trying to solve these problems in terms of library functions. Adapting the solution from this older answer of mine to your problem:
deleteFirst x xs = beforeX ++ afterX
-- Split the list into two pieces:
-- * prefix = all items before first x
-- * suffix = all items after first x
where (beforeX, xAndLater) = break (/=x) xs
afterX = case xAndLater of
[] -> []
(_:xs) -> xs
The trick is that break already has the "up to first hit" behavior built in it. As a further exercise, you can try writing your own version of break; it's always instructive to learn how to write these small, generic and reusable functions.

Related

Different result in OCaml and ReasonML

There is a case mapping two vectors into a single vector. I expected that the result of both ML should be same. Unfortunately, the result of ReasonML is different. Please help and comment how to fix it.
OCaml
List.map2 (fun x y -> x+y) [1;2;3] [10;20;30];;
[11;;22;;33]
ReasonML
Js.log(List.map2 ( (fun (x,y) => x+y), [1,2,3], [10,20,30]))
[11,[22,[33,0]]]
This is the same result. If you run:
Js.log([11,22,33]);
You'll get:
[11,[22,[33,0]]]
The result is the same, but you're using different methods of printing them. If instead of Js.log you use rtop or sketch.sh, you'll get the output you expect:
- : list(int) = [11, 22, 33]
Js.log prints it differently because it is a BuckleScript binding to console.log, which will print the JavaScript-representation of the value you give to it. And lists don't exist in JavaScript, only arrays do.
The way BuckleScript represents lists is pretty much the same way it is done natively. A list in OCaml and Reason is a "cons-cell", which is essentially a tuple or a 2-element array, where the first item is the value of that cell and the last item is a pointer to the next cell. The list type is essentially defined like this:
type list('a) =
| Node('a, list('a))
| Empty;
And with this definition could have been constructed with:
Node(11, Node(22, Node(33, Empty)))
which is represented in JavaScript like this:
[11,[22,[33,0]]]
^ ^ ^ ^
| | | The Empty list
| | Third value
| Second value
First value
Lists are defined this way because immutability makes this representation very efficient. Because we can add or remove values without copying all the items of the old list into a new one. To add an item we only need to create one new "cons-cell". Using the JavaScript representation with imagined immutability:
const old = [11,[22,[33,0]]];
const new = [99, old];
And to remove an item from the front we don't have to create anything. We can just get a reference to and re-use a sub-list, because we know it won't change.
const old = [11,[22,[33,0]]];
const new = old[1];
The downside of lists is that adding and removing items to the end is relatively expensive. But in practice, if you structure your code in a functional way, using recursion, the list will be very natural to work with. And very efficient.
#Igor Kapkov, thank you for your help. Base on your comment, I found a pipeline statement in the link, there is a summary.
let a = List.map2 ( (fun (x,y) => x+y), [1,2,3], [10,20,30] )
let logl = l => l |> Array.of_list |> Js.log;
a |> logl
[11,22,33]

How to implement recursive function to simplify polynomial terms with sorted tuple list?

I'm trying to implement a function to add like terms of a sorted list of tuples (first number represents polynomial's constant, the second represents the power). I'm an ocaml noob and don't really know what I'm doing wrong or how to do this correctly.
I tried to write it, but it doesn't work
https://gyazo.com/d37bb66d0e6813537c34225b6d4048d0
let rec simp list =
match list with
| (a,b)::(c,d)::remainder where b == d -> (a+c,b)::simp(remainder)
| (a,b)::(c,d)::remainder where b != d -> (a,b)::(c,d)::simp(remainder)
| _ -> list;;
This should combine all the terms with the same second value and just return one tuple with their first values added to the new list. ie: [(3,2);(4,2)] -> [(7,2)].
I am not familiar with the where keyword - there is ocaml-where which provides it, but it seems to be doing something different than what you are expecting. As such, the syntax is just wrong, and where is unexpected.
You probably meant when instead of where.

Get "real" prefixes/suffixes/infixes in Prolog

the Prolog notation of prefix/suffix is a quite easy one:
It pretty much puts all the work on append.
For those who don't know:
prefix(P,L):-append(P,_,L).
suffix(S,L):-append(_,S,L).
Now this means, that the result for prefix(X,[a,b,c,d]).
will be: X=[];X=[a];X=[a,b];X=[a,b,c];X=[a,b,c,d]
Here is my problem with this: I want a "real" prefix. Hence, a prefix cannot be empty, nor can the part following it be empty.
So the result to the query prefix(X,[a,b,c,d]). should be
X=[a];X=[a,b];X=[a,b,c]
and that's it.
Unfortunately, the real beaty of the standard-built in prefix predicate is, that it can use the termination of append, which is append([],Y,Y).
So it is pretty easy to know when to stop, picking the list apart one by one till the list is empty.
My termination means: Stop if there is exactly one element left in your list.
How do I do this?
My naive result would be:
prefix(P,L):-
length(P,1),append(P,E,L),E/=[].
This feels wrong though. I'm at work so I haven't checked if this actually works, but it should:
Is there any more convenient way to do this?
Same goes for suffix, which will be even harder since you do not have a way to adress the Tail as specific as the Head, I guess I'd just reverse the whole thing and then call prefix on it.
Infix will just be a combination of two.
I hope it is clear what I mean. Thanks for your input!
tl;dr: How to write a predicate prefix/2 which only filters real prefixes, so the prefix itself can not be empty, nor can the list followed by it be empty.
For the real prefix, you can try to do it like this:
list_prefix(List, [H|T]) :-
append([H|T], [_|_], List).
This just says that the first argument must have at least one element, and the rest of the list must have at least one element.
And following the suggestion by #false to make it more explicit:
list_real_prefix(List, Prefix) :-
Prefix = [_|_],
Rest = [_|_],
append(Prefix, Rest, List).
The "real" suffix will be exactly the same:
list_real_suffix(List, Suffix) :-
Front = [_|_],
Suffix = [_|_],
append(Front, Suffix, List).
You can also use a DCG for this, which is descriptive:
list_prefix(P) --> non_empty_seq(P), non_empty_seq(_).
non_empty_seq([X]) --> [X].
non_empty_seq([X|Xs]) --> [X], non_empty_seq(Xs).
| ?- phrase(list_pref(P), [a,b,c,d]).
P = [a] ? a
P = [a,b]
P = [a,b,c]
no
| ?-
You can define the suffix similarly:
list_suffix(S) --> non_empty_seq(_), non_empty_seq(S).

Pattern Match Failure in List in Haskell

I have one problem with pattern matching. When I give input to (x:y:ys) the list containing 3 elements, hugs complain that there is: pattern match failure.
I guess that the problem is here
takeNearestOnes agent (y:ys) (x:nearestOnes)
because it fails to match three elements with list containing two elements
This is full code:
takeNearestOnes agent (x:y:ys) nearestOnes
| first == second = takeNearestOnes agent (y:ys) (x:nearestOnes)
| otherwise = (x:nearestOnes)
where first=(manhattanDistance x (agentCoord agent))
second=(manhattanDistance y (agentCoord agent)
How can I overcome this? Thanks in advance
Since your function is recursive and decreasing the list, you could eventually going to work you're way down to a list of 1 element, in which case your match will fail. You can fix this by adding another case of your function which handles it however you feel is appropriate
Something like
takeNearestOnes agent [x] nearestOnes = doSomething
takeNearestOnes agent [] nearestOnes = doSomethingElse
What should be the result of takeNearestOnes agent [x] nearestOnes? What should be the result of takeNearestOnes agent [] nearestOnes?
Write extra equations for these cases.

Erlang Iterating through list removing one element

I have the following erlang code:
lists:all(fun(Element) -> somefunction(TestCase -- [Element]) end, TestCase).
Where TestCase is an array. I'm trying to iterate over the list/array with one element missing.
The problem is this code takes O(N^2) time worst case because of the copies of the TestCase array everytime -- is called. There is a clear O(N) Solution in a non functional language.
saved = TestCase[0]
temp = 0
NewTestCase = TestCase[1:]
for a in range(length(NewTestCase)):
somefunction(NewTestCase)
temp = NewTestCase[a]
NewTestCase[a] = saved
saved = temp
... or something like that.
Is there an O(N) solution in erlang?
Of course there is, but it's a little bit more complicated. I am assuming that some_function/1 is indeed a boolean function and you want to test whether it returns true for every sub-list.
test_on_all_but_one([], _Acc) -> true;
test_on_all_but_one([E|Rest], Acc) ->
case somefunction(lists:reverse(Acc,Rest)) of
true -> test_on_all_but_one(Rest, [E|Acc]);
false -> false
end.
This implementation is still O(length(List)^2) as the lists:reverse/2 call will still need O(length(Acc)). If you can modify somefunction/1 to do it's calculation on a list split into two parts, then you can modify the previous call to somefunction(lists:reverse(Acc,Rest)) with somefunction(Acc, Rest) or something similar and avoid the reconstruction.
The modification depends on the inner workings of somefunction/1. If you want more help with that, give some code!
You can split the list into 2 sublists, if it's acceptable of course.
witerate(Fun, [Tail], Acc) ->
Fun([], Acc);
witerate(Fun, [Head | Tail], Acc) ->
Fun(Tail, Acc),
witerate(Fun, Tail, [Head | Acc]).