I'm trying to write a function in ML to delete an entry from a list, given an index.
So, for example, if I have a list L = [1,2,3,4,5] and want to delete 3 from the list, I can call delete(2, L), which should delete the element at index 2, which is 3.
I have a function for deleting from a list, given a specific item in the list, but was wondering how I could get an index from a list.
Below is my code from deleting a specific element from a list
fun delete(element, list_head::list_tail) =
if element = list_head then list_tail
else list_head::delete(element, list_tail);
You can use the pattern matcher to define your two base cases and then implement your delete in terms of these cases.
fun delete (_, nil) = nil
| delete (0, _::xs) = xs
| delete (i, x::xs) = x::del(i-1,xs);
Related
First things first, I know how to append to a list in f#. If I have list = [1;2;3] then I can I can do something like 5 :: list and it will give me a new list [5;1;2;3].
I have written a function however that uses the exact same syntax but instead appends it to the back of the list, and I can't for the life of my figure out why. Can someone please explain to me why the function I wrote appends and item to the back of my list instead of the front?
let menu = [("pizza",17);("hotdog",5);("burger", 12);("drink",3);("milkshake",4)]
let rec insert dict key value =
match dict with
| (k,v) :: tl when k = key -> (k,v)::tl
| (k,v) :: tl -> (k,v)::insert tl key value
| [] -> (key,value) :: []
> insert menu "bacon" 22;;
val it : (string * int) list =
[("pizza", 17); ("hotdog", 5); ("burger", 12); ("drink", 3);
("milkshake", 4); ("bacon", 22)]
I don't really care one way or the other where it gets added to my list, I just don't understand why it's going on the end when I'm using the cons operator.
You are always inserting the new pair in front of an empty list, which is the last tail at the end of the actual list.
So if we consider this example:
insert [(1, 2)] 3 4
// Returns [(1, 2); (3, 4)]
[(1, 2)] can also be written like this:
(1, 2) :: []
And your code is effectively doing this:
(1, 2) :: (3, 4) :: []
Your insert is a recursive function. You go through each element until you hit the bottom the empty list. If you didn't found the element, then you return a one-element list with the element added. Because your are at the bottom, now all elements before you walked through your list gets added on top of this.
So overall, your new item gets added at the the end, or appended.
Hello is there a way to change the value of the head of a list in Erlang
Hd -> store2(Key, N,[New|List],New,false)
this is as close I came to changing it New is the new element to the Head element of the list
store(Key, N, TupleList, New) when is_integer(N), N > 0, is_tuple(New) ->
store2(Key, N, TupleList, New, false).
store2(_Key,_N,[], New, false) -> [New];
store2(Key, N,List, New, false) -> case fetch(Key, N, List) of
[] -> List;
false -> List++[New];
Hd -> store2(Key, N,[New|List],New,false)
end.
to clarify even further im using a function called fetch that I defined to find an element to replace with another element which is New
Just prepend your new head to the tail of List.
[New|tl(List)]
You usually write it as pattern matching
some_function(..., [_Old|Tail] = _List, ...)->
...
NewList = [New|Tail],
...
I´m trying to write a function that produces a new list containing the given list without the element x.
Moscow ML says that some cases are unused in this match.
fun delete (x,list) = delete(x,[])
|delete(x,(first::rest)) = if first = x then delete(x,rest) else first::delete(x,rest)
Here's how I'd do it on Standard ML::
fun delete (item, list) =
case list of
[]=>[]
| xs::ys => if item = xs then delete(item,ys)
else xs::delete(item,ys)
Without using cases:
fun delete (item, list) = List.filter(fn x => x <> item) list
Nevermind the polyequal signs.
When a call to delete is performed, the patterns defining the function are (essentially) tried in order. Since the first pattern already matches every list, the second pattern will never be reached. That's why the compiler complains.
In other words, you either have to reorder your cases, or better, make them disjoint (e.g. by replacing list with [] in the first case).
Extra hint: The right-hand side of the first case also seems wrong. This will always go into an infinite recursion.
That's because your first case matches any list, so the second case will never be used.
Remember that the case are tried in the order they're written, not selected based on which is the "best" match.
You also have a slight problem of infinite recursion with
delete (x,list) = delete(x,[])
Since list will match [], it will just recurse forever.
If you delete something from an empty list, the result should be the empty list.
You can do one of two things.
Either move the non-empty case first:
fun delete (x, y:ys) = if y = x then delete(x, ys) else y::delete(x, ys)
| delete (x, list) = []
Or, more common, make the first case only match the empty list:
fun delete (x, []) = []
| delete (x, y:ys) = if y = x then delete(x, ys) else y::delete(x, ys)
How can I remove the last element in a list in Standard ML?
I have a list defined as:
val list = [1, 4, 6, 8, 9]
and I want to remove the last element and have the list in the val list.
Well you have various ways of doing it.
You could take the original list apart, and start building a new list with the elements, until you reach the last element.
fun f [] = ...
| f [x] = ...
| f (x::xs) = x :: ...
Or you could use the List.take function to take the first i elements from the list. Obviously you could use the List.length function to calculate how many elements you wan't to take from the list.
fun h xs = List.take (xs, ...)
Hey, I'm trying to learn some f# basics and am stumbling along. I'm wondering how you would go about "replacing" the first element in a list.
Any help would be appreciated!
Here's a general purpose function. It will replace the head of a list with a new value if the list is non-empty, else it will return a single element list with the replace value.
let replaceHead newHead list =
match list with
| _ :: tail -> newHead :: tail
| [] -> [newHead]
You could 'cons' (using the ::-operator) the new first element to the tail (List.tail) of the original list:
let theList = [1; 2; 3; 4]
let firstReplaced = 0 :: (List.tail a)
Note that this will leave the original list (theList) untouched.