Walk through list using elements, but not losing elements Haskell - list

I am looking for a way of walking through a list, grabbing an element (in that order its given I suppose), using it with another function, then returning to that list and continuing the operation WITHOUT losing that element from the list.
In examples I've seen the only way to accomplish this would be to do the following:
counter :: (Eq a1, Num a) => a1 -> [a1] -> a
counter a [] = 0
counter a [x] = if a == x then 1 else 0
counter a (x:xs) = if a == x then counter a xs + 1 else counter a xs
permut :: Eq a => [a] -> [a] -> Bool
permut [] [] = True
permut [x] [] = False
But this gets rid of the element x from the list xs when called again both within permut. I know that this also serves to end the recursive calls/terminate the function, but I need to have the whole list available in my counter function in order for it to work. I want to simply walk through the list and keep the whole thing intact. Is this possible?
EDIT: Updated use case. I am trying to work on checking if one list is a permutation of another. My thought process is within each list two properties will hold if they are a permutation:
They will have the same number of total elements (will implement this piece later)
They will have the same number of each element
Right now my counter function works, but I am losing elements as I iterate recursively through the permut function. I don't care about efficiency, I don't mind counting the same element again and comparing it if the number shows up in the list multiple times.

Your pattern match is a bit too exhaustive, and you need to check your condition for all elements. It should look like:
permut [] ys = null ys
permut xs ys = all condition xs
where
condition x = ....
Bonus suggestion: Whenever it is the case that it is true that you find yourself writing
if ..... then True else False
you write to much.
----- Addendum:
So you found all, it does walk through the list (xs in our case) and it checks if the condition is True for all elements (of xs in our case). For example:
all even [1,2,3]
is a short way to say:
even 1 && even 2 && even 3
So, in your where clause you have condition, and it has access to the original xs and ys lists, and it is called for each element in xs. Hence, all you need to check is if the argument x of condition occurs the same number of times in xs and ys. For this, you have already counter, so it'll be a one liner.

Related

Insert number into sorted list using List.fold_right

I am trying to insert a number x into a sorted list l using Ocaml's List.fold_right and return the list with the inserted element. I have figured out a way to insert it if the element is to go at the front of the list or in the middle of the list, however I cannot figure out how to code the case where the element is larger than every element in the list and thus must go at the end.
Here is what I have so far:
let insert_number (x: int) (l: int list): int list =
List.fold_right l ~f:(
fun cur -> fun acc ->
if x < cur then cur::x::accum
else cur::accum
) ~init: []
Using this with a test case like:
insert_number (3) ([1; 2; 4]);;
- : int list = [1; 2; 3; 4]
gives the correct answer. However, with a test case like this:
insert_number (3) ([1; 2]);;
- : int list = [1; 2]
the number is not inserted because it should be added to the end of the list.
Could someone help me understand how I am supposed to integrate this case into the function used with List.fold_right.
A fold works by passing along a set of state as it iterates over each element in a list (or other foldable data structure). The function passed in takes both the current element and that state.
I think you're really really close, but you need as Jeffrey suggests a boolean flag to indicate whether or not the value has been inserted. This will prevent multiple insertions and if the flag is still false when the fold is done, we can detect that and add the value to insert.
This match also serves the purpose of giving us an opportunity to discard the no longer needed boolean flag.
let insert v lst =
match List.fold_right
(fun x (inserted, acc) ->
if v > x && not inserted then (true, x::v::acc)
else (inserted, x::acc))
lst
(false, []) with
| (true, lst) -> lst
| (_, lst) -> v::lst
One way to look at List.fold_right is that it looks at each element of the list in turn, but in reverse order. For each element it transforms the current accumulated result to a new one.
Thinking backward from the end of the list, what you want to do, in essence, is look for the first element of the list that's less than x, then insert x at that point.
So the core of the code might look something like this:
if element < x then element :: x :: accum else element :: accum
However, all the earlier elements of the list will also be less than x. So (it seems to me) you need to keep track of whether you've inserted x into the list or not. This makes the accumulated state a little more complicated.
I coded this up and it works for me after fixing up the case where x goes at the front of the list.
Perhaps there is a simpler way to get it to work, but I couldn't come up with one.
As I alluded to in a comment, it's possible to avoid the extra state and post-processing by always inserting the element and effectively doing a "local sort" of the last two elements:
let insert_number x l =
List.fold_right (
fun cur -> function
| [] when x > cur -> [cur; x]
| [] -> [x; cur]
| x::rest when x > cur -> cur::x::rest
| x::rest -> x::cur::rest
) l []
Also, since folding doesn't seem to actually be a requirement, here's a version using simple recursion instead, which I think is far more comprehensible:
let rec insert_number x = function
| [] -> [x]
| cur::rest when cur > x -> x::cur::rest
| cur::rest -> cur::insert_number x rest

how to add a number in a 2D list with specific index in haskell

I'm beginner in haskell and I tried to add a number in a 2D list with specific index in haskell but I don't know how to do
example i have this:
[[],[],[]]
and I would like to put a number (3) in the index 1 like this
[[],[3],[]]
I tried this
[array !! 1] ++ [[3]]
but it doesn't work
As you may have noticed in your foray so far, Haskell isn't like many other languages in that it is generally immutable, so trying to change a value, especially in a deeply nested structure like that, isn't the easiest thing. [array !! 1] would give you a nested list [[]] but this is not mutable, so any manipulations you do this structure won't be reflected in the original array, it'll be a separate copy.
(There are specialized environments where you can do local mutability, as with e.g. Vectors in the ST monad, but these are an exception.)
For what you're trying to do, you'll have to deconstruct the list to get it to a point where you can easily make the modification, then reconstruct the final structure from the (modified) parts.
The splitAt function looks like it will help you with this: it takes a list and separates it into two parts at the index you give it.
let array = [[],[],[]]
splitAt 1 array
will give you
([[]], [[],[]])
This helps you by getting you closer to the list you want, the middle nested list.
Let's do a destructuring bind to be able to reconstruct your final list later:
let array = [[],[],[]]
(beginning, end) = splitAt 1 array
Next, you'll need to get at the sub-list you want, which is the first item in the end list:
desired = head end
Now you can make your modification -- note, this will produce a new list, it won't modify the one that's there:
desired' = 3:desired
Now we need to put this back into the end list. Unfortunately, the end list is still the original value of [[],[]], so we'll have to replace the head of this with our desired' to make it right:
end' = desired' : (tail end)
This drops the empty sub-list at the beginning and affixes the modified list in its place.
Now all that's left is to recombine the modified end' with the original beginning:
in beginning ++ end'
making the whole snippet:
let array = [[],[],[]]
(beginning, end) = splitAt 1 array
desired = head end
desired' = 3:desired
end' = desired' : (tail end)
in beginning ++ end'
or, if you're entering all these as commands in the REPL:
let array = [[],[],[]]
let (beginning, end) = splitAt 1 array
let desired = head end
let desired' = 3:desired
let end' = desired' : (tail end)
beginning ++ end'
As paul mentions, things in Haskell are immutable. What you want to do must be done not be modifying the list in place, but by destructuring the list, transforming one of its parts, and restructuring the list with this changed part. One way of destructuring (via splitAt) is put forth there; I'd like to offer another.
Lists in Haskell are defined as follows:
data [] a = [] | a : [a]
This reads "A list of a is either empty or an a followed by a list of a". (:) is pronounced "cons" for "constructor", and with it, you can create nonempty lists.
1 : [] -> [1]
1 : [2,3] -> [1,2,3]
1 : 2 : 3 : [] -> [1,2,3]
This goes both ways, thanks to pattern matching. If you have a list [1,2,3], matching it to x : xs will bind its head 1 to the name x and its tail [2,3] to xs. As you can see, we've destructured the list into the two pieces that were initially used to create it. We can then operate on those pieces before putting the list back together:
λ> let x : xs = [1,2,3]
λ> let y = x - 5
λ> y : xs
[-4,2,3]
So in your case, we can match the initial list to x : y : z : [], compute w = y ++ [3], and construct our new list:
λ> let x : y : z : [] = [[],[],[]]
λ> let w = y ++ [3]
λ> [x,w,z]
[[],[3],[]]
But that's not very extensible, and it doesn't solve the problem you pose ("with specific index"). What if later on we want to change the thousandth item of a list? I'm not too keen on matching that many pieces. Fortunately, we know a little something about lists—index n in list xs is index n+1 in list x:xs. So we can recurse, moving one step along the list and decrementing our index each step of the way:
foo :: Int -> [[Int]] -> [[Int]]
foo 0 (x:xs) = TODO -- Index 0 is x. We have arrived; here, we concatenate with [3] before restructuring the list.
foo n (x:xs) = x : foo (n-1) xs
foo n [] = TODO -- Up to you how you would like to handle invalid indices. Consider the function error.
Implement the first of those three yourself, assuming you're operating on index zero. Make sure you understand the recursive call in the second. Then read on.
Now, this works. It's not all that useful, though—it performs a predetermined computation on a specified item in a list of one particular type. It's time to generalize. What we want is a function of the following type signature:
bar :: (a -> a) -> Int -> [a] -> [a]
where bar f n xs applies the transformation f to the value at index n in the list xs. With this, we can implement the function from before:
foo n xs = bar (++[3]) n xs
foo = bar (++[3]) -- Alternatively, with partial application
And believe it or not, changing the foo you already wrote into the much more useful bar is a very simple task. Give it a try!

OCaml - splitting list into two separate, greater or lesser than given number

I have a problem with writing a function which result is as shown below:
split([7;1;4;3;6;8;2], 4) = ([1;3;2;4], [7;6;8])
my current code i managed to write:
let split(list, number)=
let split1(list, number, lesser, greater)=
if list = [] then lesser::greater
else if List.hd list <= element then (List.hd list)::(lesser)
else (List.hd list)::(greater)
in
(List.tl lista, element, [], []);;
Thanks in advance for your help.
For the future, it helps to be more specific when asking a question on SO. What exactly is your problem? SO users will be skeptical of someone who wants others to help them, but won't help themselves.
Your code has nearly the correct structure, but there are a few errors in there that seem to be getting in your way.
Firstly lesser::greater is wrong, since the left hand side of a cons operator must be a list itself, but what you really want is a list where both of these are elements. So instead try [lesser;greater].
Secondly, if you think through your code, you will notice that it suddenly stops. You checked the first element, but you didn't look at the rest of the list. Since you want to keep splitting the list, you need your code to keep executing till the end of the list. To achieve this, we use recursion. Recursion mean that your function split1 will call itself again. It can be very confusing the first time you see it - each time split1 runs it will take the first element off, and then split the remainder of the list.
What does (List.hd list)::(lesser) actually mean? The lesser here really means all of the lesser elements in the rest of the list. You need to keep taking an element out of the list and putting it in either lesser or greater.
Finally avoid using List.hd excessively - it is neater to find the head and tail using pattern matching.
Here's a working version of the code:
let split(list, number)=
let rec split1(list, number, lesser, greater)=
match list with
| [] -> [List.rev lesser;List.rev greater]
| head::tail ->
match (head <= number) with
true -> split1(tail,number,head::lesser,greater)
| false -> split1(tail,number,lesser,head::greater)
in split1(list, number, [], []);;
split([1;2;3;4;5],3);;
The split1 function takes the elements off one at a time, and adds them to the lists.
Maybe my comments on the following code snippet would help:
let split list num =
let rec loop lesser greater list =
match list with
| [] -> (lesser, greater)
(* when your initial list is empty, you have to return the accumulators *)
| x :: xs ->
if x <= num then
(* x is lesser than num, so add x in the lesser list and
call loop on the tail of the list (xs) *)
else
(* x is greater than num, so add x in the greater list and
call loop on the tail of the list (xs) *)
in
(* here you make the first call to loop by initializing
your accumulators with empty list*)
loop [] [] list

Inserting an integer into a list at specific place

I want to make a program insertAt where z is the place in the list, and y is the number being inserted into the list xs. Im new to haskell and this is what I have so far.
insertAt :: Int-> Int-> [Int]-> [Int]
insertAt z y xs
| z==1 = y:xs
but I'm not sure where to go from there.
I have an elementAt function, where
elementAt v xs
| v==1 = head xs
| otherwise = elementAt (v-1) (tail xs)
but I'm not sure how I can fit it in or if I even need to. If possible, I'd like to avoid append.
If this isn't homework: let (ys,zs) = splitAt n xs in ys ++ [new_element] ++ zs
For the rest of this post I'm going to assume you're doing this problem as homework or to teach yourself how to do this kind of thing.
The key to this kind of problem is to break it down into its natural cases. You're processing two pieces of data: the list you're inserting into, and the position in that list. In this case, each piece of data has two natural cases: the list you're procssing can be empty or not, and the number you're processing can be zero or not. So the first step is to write out all four cases:
insertAt 0 val [] = ...
insertAt 0 val (x:xs) = ...
insertAt n val [] = ...
insertAt n val (x:xs) = ...
Now, for each of these four cases, you need to think about what the answer should be given that you're in that case.
For the first two cases, the answer is easy: if you want to insert into the front of a list, just stick the value you're interested in at the beginning, whether the list is empty or not.
The third case demonstrates that there's actually an ambiguity in the question: what happens if you're asked to insert into, say, the third position of a list that's empty? Sounds like an error to me, but you'll have to answer what you want to do in that case for yourself.
The fourth case is most interesting: Suppose you want to insert a value into not-the-first position of a list that's not empty. In this case, remember that you can use recursion to solve smaller instances of your problem. In this case, you can use recursion to solve, for instance, insertAt (n-1) val xs -- that is, the result of inserting your same value into the tail of your input list at the n-1th position. For example, if you were trying to insert 5 into position 3 (the fourth position) of the list [100,200,300], you can use recursion to insert 5 into position 2 (the third position) of the list [200,300], which means the recursive call would produce [200,300,5].
We can just assume that the recursive call will work; our only job now is to convert the answer to that smaller problem into the answer to the original problem we were given. The answer we want in the example is [100,200,300,5] (the result of inserting 5 into position 4 of the list [100,200,300], and what we have is the list [200,300,5]. So how can we get the result we want? Just add back on the first element! (Think about why this is true.)
With that case finished, we've covered all the possible cases for combinations of lists and positions to update. Since our function will work correctly for all possibilities, and our possibilities cover all possible inputs, that means our function will always work correctly. So we're done!
I'll leave it to you to translate these ideas into Haskell since the point of the exercise is for you to learn it, but hopefully that lets you know how to solve the problem.
You could split the list at index z and then concatenate the first part of the list with the element (using ++ [y]) and then with the second part of the list. However, this would create a new list as data is immutable by default. The first element of the list by convention has the index 0 (so adjust z accordingly if you want the meaning of fist elemnt is indexed by 1).
insertAt :: Int -> Int-> [Int] -> [Int]
insertAt z y xs = as ++ (y:bs)
where (as,bs) = splitAt z xs
While above answers are correct, I think this is more concise:
insertAt :: Int -> Int-> [Int]-> [Int]
insertAt z y xs = (take z xs) ++ y:(drop z xs)

Haskell Check if a list of Int's is complete

Not easy way to explain this, but I will try. I think i'm confusing my method with some C, but here it goes:
I want to check if a list is complete, like this:
main> check 1 [1,3,4,5]
False
main> check 1 [1,2,3,4]
True
It's a finite list, and the list doesn't have to be ordered. But inside the list there most be the number that misses to be True. In the first case it's the number 2.
This is my version, but it doesn't even compile.
check :: Eq a => a -> [a] -> Bool
check n [] = False
check n x | n/=(maximum x) = elem n x && check (n+1) x
| otherwise = False
So if I understand this correctly, you want to check to see that all the elements in a list form a sequence without gaps when sorted. Here's one way:
noGaps :: (Enum a, Ord a) => [a] -> Bool
noGaps xs = all (`elem` xs) [minimum xs .. maximum xs]
[minimum xs .. maximum xs] creates a sequential list of all values from the lowest to the highest value. Then you just check that they are all elements of the original list.
Your function doesn't compile because your type constraints are greater than what you declare them as. You say that a only needs to be an instance of Eq - but then you add something to it, which requires it to be an instance of Num. The way you use the function also doesn't make sense with the signature you declared - check [1,2,3,4] is a Bool in your example, but in the code you gave it would be Eq a => [[a]] -> Bool (if it compiled in the first place).
Do you only need this to work with integers? If not, give some example as to what "complete" means in that case. If yes, then do they always start with 1?
Here's another take on the problem, which uses a function that works on sorted lists, and use it with a sorted input.
The following will check that the provided list of n Int contains all values from 1 to n:
check :: (Num a, Ord a) => [a] -> Bool
import List
check l = check_ 1 (sort l)
where check_ n [] = True
check_ n [x] = n == x
check_ n (x:y:xs) = (x+1)==y && check_ (n+1) (y:xs)
Note the use of List.sort to prepare the list for the real check implemented in check_.