Append to beginning of List F# - list

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.

Related

Changin list which is an iput with function

Good morning,
I have a problem with coding using ocaml so I had to code a function that take on input list then add to this list an element.
But using this does'nt affect the list1 so how can I do this ?
Thank you.
let rec append list1 element list2 = match list2 with
[]-> list1
| e::l -> if ( element = e ) then e :: list1
else (append list1 element l)
;;
List are immutable in OCaml, you can't change this. You can write a function append that takes a list and returns a new list that appends an element to it.
For example, here is the prepend function that takes a list and an element and returns a new list with the given element prepended to the passed list,
let prepend xs x = x :: xs
The append function is a little bit trickier, since lists in OCaml are singly-linked, so it is easy to prepend but hard to append. To implement the append function you need an intermediate list, let's call it acc for accumulator. You then go through each element of the input list and add it to the accumulator. Since you're prepending, then once the input list is over your accumulator will have all the elements of the input list by in the reversed order, i.e., the first element (aka the head) of the acc list will be the last element of the input list. Now you what is left is to prepend the element that we want to append to the reversed acc list and reverse act. Here is the skeleton code for you
let append xs x =
let rec loop xs acc = match xs with
| ... -> ... in
loop xs []

How to move 1 element of a List to right or left in Haskell?

Hi I have been looking for an answer but could not find one. Lets say that we have a list like [1,10,4,5,3] how can I shift 5 to left so that this list becomes [1,10,5,4,3].
I tried to swapElementsAt by finding the index of that element but it looks very insufficient.
swapElementsAt :: Int -> [a] -> [a]
swapElementsAt n list = let (beg, a:b:rest) = splitAt (n-1) list in beg ++ b:a:rest
It works like
λ> swapElementsAt 3 [1,10,4,5,3]
[1,10,5,4,3]
Consider how would you write this function if you were to traverse the input list from left to right looking at a very local vicinity of the beginning of the list (since that's what you can easily pattern-match on).
The most straightforward way would be to pattern-match on the first two elements, and check if the second element matches your pattern. If so, just build a new list by swapping these elements and appending the remainder of the list, otherwise, go recursively over the rest.
In code:
swapElem :: Eq a => a -> [a] -> [a]
swapElem e (x:y:xs) | y == e = y : x : xs
swapElem e (x:xs) = x : swapElem e xs
swapElem _ [] = []
The first pattern only matches when there are at least two elements in the list, and the second element is equal to the desired one. If there are less elements or the second element is not the right one, it will fall through to the second pattern, that matches arbitrary non-empty list and calls swapElem on the remainder of the list. The third pattern is there to provide the base recursion case of an empty input list.
Note this code only changes the first occurrence of the target element:
Prelude> swapElem 5 [1, 10, 4, 5, 3]
[1,10,5,4,3]
Prelude> swapElem 5 [1, 10, 5, 4, 5, 3]
[1,5,10,4,5,3]
How would you change it so that it left-shifts all 5s?
Also, the answer depends on what exactly is your input. The answer by #Scarabyte considers the case where you're given the position of the target element, while this approach instead considers the element that you want to shift left.

K out on N implementation - SML

I was trying to implement k-out-of-N at SML so "pick(3,[1,2,3,4])" will return [[1,2,3],[1,3,4]...] (all the K-size picks out of N elements)
I used List.map which I figured it calls the function and apply it on each element.
Really can't figure out why when typing the input "pick(3,[1,2,3,4,5])" ,for example, it return an empty list.
My first thought was that it's because of the initial terms (choose (_,[]) = [])
But changing it didn't work as well.
The signature is ok (val pick = fn : int * 'a list -> 'a list list).
fun pick (_,[]) = []
| pick (0,_) = []
| pick (n,hd::tl) =
let
val with_hd = List.map (fn x => hd::x) (pick(n-1,tl))
val without_hd = pick(n,tl)
in
with_hd#without_hd
end;
The problem is related to your suspicion – the base cases are incorrect in that they always produce the empty list, and mapping fn x => hd::x onto the empty list produces the empty list.
Picking zero elements from anything should succeed, and produce the empty list.
That is, pick (0, _) = [[]] — a list with one element, which is the empty list.
You also need to rearrange the cases since pick(n, []) succeeds for n = 0 but not for any other n.
In summary,
fun pick (0, _) = [[]]
| pick (_, []) = []
with the rest of the function exactly as before.

Move items up in a list

How do you move items up in a list.
The input list would look like: let list = [1;2;3;4;5]
And the output list would look like one of the following:
[1;2;3;5;4]
.........>
[2;1;3;4;5]
...>......
Plot twist: I want to be able to move any index in the list up
From what I understand is this not something you aim to do with F# or functional languages, but it's a must have on my program.
I believe this can be done using both recursions and higher order(HO) functions, but since my knowlegde with HO's are very limited I tried to solve this using a recursion.
My approach to moving down an item in the list included a simple recursion with index and list as arguments like so:
let rec moveDownAt index list =
match index, list with
| -1, _ -> list
| 0, h1::h2::t -> h2::h1::t
| index, h::t -> h::moveDownAt (index - 1) t
| _, [] -> list
However, to move in the other direction I would need to reference the previous "head" and I assume I would have issues on the third match line | index, h::t -> h::moveDownAt (index - 1) t where i perform h:: since I add the head to the list (which would be the previous the next call if I add that argument).
Switching place on two elements means that one is moving up, and one is moving down.
Simple using the following code will solve the problem:
let moveUpAt index list = moveDownAt (index-1) list
This will displace the index making "index to be moved down" turn into "index to be moved up".
The basic idea is the following: First, return the nth element of the list. Then append the rest elements, except the nth element since you have already returned it. Here's the code:
let MoveToTop index xs =
List.nth xs index // take nth item
:: // and prepend it to the beginning of the
// original list, except the nth element
(
xs // original data
|> List.mapi
(fun i x -> i, x) // associate each element with its ordinal index
|> List.filter
(fun (i, _) -> i <> index) // allow only the elements whose index
// is not equal to requested index
|> List.map snd // remove the index from the data
// as we no longer need it
)
// test
[1; 2; 3; 4; 5]
|> MoveToTop 1 // don't forget, the index is zero-based
|> printfn "%A"
// output: [2; 1; 3; 4; 5]
Note that if index is outside the length of the list, an ArgumentException will be thrown.
A recursive algorithm is also possible, but it would be certainly less performant due to creation of excessive data and performing excessive computations.

remove last element of a list sml by keeping the list in a val

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, ...)