Haskell count occurrences in two dimensional lists - list

I have to count the occurrences in a two dimensional (2D) list [[Int]], but I get errors.
What I tried so for is counting 1D. It works fine like this:
instances::Int->[Int]->Int
instances x [] = 0
instances x (y:ys)
| x==y = 1+(instances x ys)
| otherwise = instances x ys
Could you please help me to modify this function in order to count a 2D list:
instances::Int->[Int]->Int
Thanks in advance
Greetings

instances2D x = length . filter (==x) . concat
or
instances2D y xss = sum [1 | xs <- xss, x <- xs, y == x]

With your explicit recursion (v. a library function that hides the recursion), all you need is a function that can step through the elements of your 2D list. If you can write a function that steps through each element of your 2D list and gets each sub-list into a variable, then you can call your 1D function on that variable. And stepping through the elements of any list is easy with pattern matching:
matchesIn2DList:: Int -> [[Int]] -> Int
matchesIn2DList _ [] = 0 --> [] is an empty 2D list
matchesIn2DList x (l:ls) =
(matchesIn1DList x l) + (matchesIn2DList x ls)
Note that in the your base case:
instances x [] = 0
the value being searched for is immaterial: the count for the matches in an empty list will always be 0 no matter what value you are searching for, so you can use _ instead of a variable name.

Related

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!

removing duplicates from a list in haskell

I am trying to delete consecutive duplicates in a list; for instance, given the list [1,2,2,3,4], it the function I need must return [1,3,4].
My code at the end of the question, however, doesn't work if trailing duplicates are in list, like in [1,2,3,4,4].
I also want to do it in as simple terms as possible, how can I do this?
myCom :: Eq a => [a] -> [a]
myCom (x:y:ys#(z:_))
| x == y = myCom ys
| otherwise = x : myCom (y:ys)
myCom ys = ys
The first pattern match you have only catches lists with at least 3 elements.
That is why when the duplicates are at the end of the list when
myCom [4,4]
is called it simply uses
myCom ys = ys
and returns itself. You can catch this by defining myCom for lists with at least 2 elements as below (you werent't using z anyway):
myCom (x:y:ys)
| x == y = myCom ys
| otherwise = x : myCom (y:ys)
myCom ys = ys
This gives
myCom [1,2,2,3,4,4] = [1,3]
There is still an issue with 3 (an odd number) consecutive numbers. For example we get:
myCom [1,2,2,2] = [1,2]
but I understand that this is desired behavior.
I would use Maybe to represent a length of one as a success condition. This works well with Haskell's pattern-matching syntax. You can then use group (from Data.List) and filter out the Nothings using catMaybe (from Data.Maybe) :
myCom = catMaybes . map lenOne . group
where lenOne [x] = Just x
lenOne _ = Nothing
From a comment I see that the function Data.Set.nub just does what the OP asks.
However, my first attempt to solve the problem was the following, which only removes duplicates if they are consecutive (e.g. [1,2,1,2,1,2] is not changed):
concat $ filter (\x -> length x == 1) $ Data.List.group [1,2,3,4,4]
I hope this answer could be useful to some random user ending up on this page.

Circular maps in haskell

I'm tasked with implementing a function that returns the Thue-Morse sequence all the way through. I've done it through primitive recursion but now I have to do it with a circular list (using list comprehension), and it'd have to return this when I call take on it:
>take 4 thueSeq
[[0],[0,1],[0,1,1,0],[0,1,1,0,1,0,0,1]]
Here's my (horrible) attempt at implementation:
> thueSeq = 0: [x | x <- zipWith (mod) (tail thueSeq) [1] ]
I'm aware right off the bat that it's wrong (the head is supposed to be [0], not 0) but writing [0] ++ [0,1] ++ ... didn't return a list of lists anyway.
My question is, first off, how do I "start off" the list with [[0],[0,1]] because from what I've seen with circular lists, they have the base cases and then recurse through. Secondly, my list comprehension is trying to apply (mod x 1) to each value, but that'd also be wrong since [[0,1]] would turn into [[0,1,0]] instead of [[0,1,1,0]]. So I'm thinking I have to apply it on every other element in the list (the 1st element, 3rd, 5th, etc.)?
From what I understand...
I have just written a simple flip function that maps 1 to 0 and 0 to 1
flipBit 1 = 0
flipBit 0 = 1
the function h takes a list and joins that list with the flipped version of the list
h xs = xs ++ (map flipBit xs)
*Main> h [0]
[0,1]
The main function fseq takes a list as an argument. It conses the argument into the recursive call
fseq xs = xs : fseq (h xs)
*Main> take 4 $ fseq [0]
[[0],[0,1],[0,1,1,0],[0,1,1,0,1,0,0,1]]
Haskell provides the function iterate :: (a -> a) -> a -> [a] that does exactly this.
We can now wrap this as follows:
thue_morse = fseq [0]
or using the function iterate
thue_morse = iterate h [0]
both give the result
*Main> take 4 thue_morse
[[0],[0,1],[0,1,1,0],[0,1,1,0,1,0,0,1]]
If you wanted to use list comprehensions, you could write something like this:
h xs = xs ++ (map flipBit xs)
thue_morse = [0] : [ h x | x <- thue_morse]

Haskell List Comprehension, where x can't be equal to an element of a list

I want to generate a list of tuples from a list of tuples, where the left part of the tuple only occurs on the left side in all the elements of the list.
Basically what I want is a more generalized version of the following:
[ (x,y) | (x,y) <- [(1,5),(5,2)], x /= 5, x /=2 ]
If [(1,5),(5,2)] would be a variable called list, then x can't be equal to any of the values of (map snd list). How do I put this condition the list comprehension? (or should I use something else? like filter?)
then x can't be equal to any of the values of (map snd list)
The direct translation of that is
x `notElem` map snd list
So you'd use something like
let xs = [(1,5),(5,2)] in [(x,y) | (x,y) <- xs, x `notElem` map snd xs]
If the list is long, that is not efficient, so then you could - if the type permits it, i.e. is an instance of Ord - build a set and check for membership in the set
let xs = [(1,5),(5,2)]
st = Data.Set.fromList (map snd xs)
in [(x,y) | (x,y) <- xs, not (Data.Set.member x st)]
to reduce the O(n²) complexity of the first to an O(n*log n) complexity.
Construct a Set of all the second elements (let's call it seconds), and then just filter by flip notMember seconds . fst. You could easily write this as a list comprehension if you really wanted to (but you'd just end up rewriting filter, so why do it?).

Haskell: A function that takes a list xs and an integer n and returns all list of length n with elements from xs

I have tried to solve this problem before, and I've searched for a solution and could never find one.
I need a function that takes a list xs and an integer n and returns all list of length n with elements from xs. For example:
function [0,1] 3 = [[0,0,0],[0,0,1],[0,1,0],[0,1,1],[1,0,0],[1,0,1],[1,1,0],[1,1,1]]
I have tried this:
list _ 0 = []
list xs n = do
y <- xs
ps <- list xs (n-1)
return y : ps
and this:
list _ 0 = []
list xs n = do
y <- xs
y : list xs (n-1)
None work as intended. I want to know two things:
Why doesn't these work?
How should I modify them so that they work?
You're very close! Your problem is your base case, list _ 0 = [].
What you're saying there is that there are no lists of length 0 with elements from xs, when in fact there is one, the empty list.
Try
list _ 0 = [[]]
list xs n = do
y <- xs
ps <- list xs (n-1)
return $ y : ps