Adding contents of two different size lists haskell - list

I am trying to implement a function that sums the contents of two lists. Here is my code:
sum'' :: Num a => [a] -> [a] -> [a]
sum'' [] [] = []
sum'' (x:xs) (y:ys) = (x + y) : sum'' xs ys
If I type in:
sum'' [1,2,3] [4,5,6]
I get [5,7,9], which is what I want. What I am having trouble with is different list sizes. If I type in:
sum'' [] [1,2,3]
I want it to return []. Or
sum'' [1,2] [4,5,6]
I want it to return [5,7]. I am getting this error and do not know why: Non-exhaustive patterns in function sum''.
Any help would be much appreciated.

When defining sum'', you have defined what it means for two empty lists, and for two non-empty lists, but you haven't defined what it means for two lists, only one of which is empty. This is what the compiler is telling you via that error message.
Simply add definitions of what sum'' means whenever left list is empty and the right list is not, and vice versa:
sum'' (x:xs) [] = ...
sum'' [] (y:ys) = ...

Well in Haskell, actually for what you need there is the ZipList type and you may use it to simply do as follows;
import Control.Applicative
addLists :: Num a => [a] -> [a] -> [a]
addLists xs ys = getZipList $ (+) <$> ZipList xs <*> ZipList ys
*Main> addLists [3] [1,2,3]
[4]

Related

infinite type error reversing a list in Haskell

I'm trying to implement the reverse of a list:
myLast :: [a] -> a
myLast [] = error "No end for empty lists!"
myLast [x] = x
myLast (_:xs) = myLast xs
myReverse :: [a] -> [a]
myReverse (x:xs) = myLast xs + myReverse xs
but I get this error:
/workspaces/hask_exercises/exercises/src/Lib.hs:42:32: error:
* Occurs check: cannot construct the infinite type: a ~ [a]
* In the second argument of `(+)', namely `myReverse xs'
In the expression: myLast xs + myReverse xs
In an equation for `myReverse':
myReverse (x : xs) = myLast xs + myReverse xs
* Relevant bindings include
xs :: [a] (bound at src/Lib.hs:42:14)
x :: a (bound at src/Lib.hs:42:12)
myReverse :: [a] -> [a] (bound at src/Lib.hs:41:1)
|
42 | myReverse (x:xs) = myLast xs + myReverse xs
| ^^^^^^^^^^^^
What does it mean that cannot construct the infinite type: a ~ [a]? I get this error a lot and would like to understand what it means.
The (+) :: Num a => a -> a -> a function adds two numbers (of the same type) together. So for example if a ~ Int, it will add two Ints together, but not an Int and a [Int].
But even if the (+) operator for example would prepend an item to a list, it would still not reverse the list correctly: your function has no base case what to do for an empty list, and your recursive list does nothing with the first item x of the list (x:xs).
A simple way to reverse:
myReverse :: [a] -> [a]
myReverse [] = []
myReverse (x:xs) = myReverse xs ++ [x]
But that is not efficient: appending two items will take linear time in the size of the left list. You can work with an accumulator: a parameter that you each time update when you make a recursive call. This looks like:
myReverse :: [a] -> [a]
myReverse [] = go []
where go ys (x:xs) = …
where go ys [] = …
where filling in the … parts are left as an exercise.
You have
myLast :: [a] -> a
myReverse :: [a] -> [a]
myReverse (x:xs) = myLast xs + myReverse xs
\___a___/ \____[a]___/
(x:xs) :: [a]
---------------
x :: a
xs :: [a] xs :: [a]
myLast :: [a] -> a myReverse :: [a] -> [a]
------------------------- ----------------------------
myLast xs :: a myReverse xs :: [a]
myReverse (x:xs) :: [a]
but
> :t (+)
(+) :: Num a => a -> a -> a
which means that the type of the thing on the left of + and the type of the thing on the right must be the same.
But they can't be: as we just saw above, in your code the first (of myLast xs) is some type a, and the second (of myReverse xs) is [a] the list of those same as.
These two can't be the same, because it would mean
a ~ [a] OK, this is given to us, then
a ~ [a] we can use it, so that
--------------
a ~ [[a]] this must hold;
a ~ [a] we know this, then
--------------
a ~ [[[a]]] this must also hold; and
a ~ [a] ........
-------------- ........
a ~ [[[[a]]]] ........
.........................
and so on ad infinitum, thus making this a an "infinite" type. Hence the error.
You could fix it by replacing the + with
(+++) :: a -> [a] -> [a]
and implementing it to do what you need it to do.
You will also need to fix your off-by-one error whereby you completely ignore the first element in the received input, x.

Sorting lists in list by length using bubble sort - Haskell

I have an input, which is of type [[a]] and I am trying to sort the lists in the list by their length. I am working on my own implementation of bubble sort, which currently looks like this:
myInput :: Ord a => [[a]] -> [[a]]
myInput [[]] = [[]]
myInput [[x]] = [[x]]
myInput (x : xs) = mySort x (myInput xs)
mySort :: Ord a => [a] -> [[a]] -> [[a]]
mySort x [[]] = [x]
mySort x (y:ys) | (length x) < (length y) = x:y:ys
| otherwise = y:(myInput x ys)
However, when I input myInput[[1,2],[1]], I get a non-exhaustive pattern error:
[[1]*** Exception: CourseworkRev.hs:(197,1)-(200,49): Non-exhaustive patterns in function myInput
I am probably doing something wrong when declaring the empty lists, as this is a recursion error (correct me if I am wrong). Any tips on how to make this working? Thanks!
myInput has no pattern for an empty list, only for a list with one element that is an empty list. You likely do not need patterns like [[]] and [[x]] anyway, since for a list with a single element, you will return a list with that element, regardless of it length, so:
myInput :: Ord a => [[a]] -> [[a]]
myInput [] = []
myInput [x] = [x]
myInput (x : xs) = mySort x (myInput xs)
[[x]] matches with a list that contains exactly one sublist [x] which is a list with one element. So this will match with [[1]], but not with [[1,2]]. [x] on the other hand matches with any singleton list: a list with one element so [[1]], [[1,4]], [[1,4,2,5]], and [[]] will all match.

Haskell: Merging a list where even indices are from list 1 and odd are from list 2. Fill with 0's if not the same size

i've tried to create a Haskell function that is merging 2 lists into a single list, where even indices in the new list are from list 1 and the odd are from list 2. Fill with 0's if not the same size.
For example:
[1] [10,15,20] => [1,10,0,15,0,20]
[2,3] [4,5] => [2,4,3,5]
I've tried to create a couple of versions but with no luck.
How can I create such a thing?
There is a interleave function, that does something similar, however, not exactly that. It 'merges' lists until one of them ends.
So you can write that function by yourself:
merge :: [Int] -> [Int] -> [Int]
merge (x:xs) (y:ys) = x : y : merge xs ys
merge (x:xs) [] = x : 0 : merge xs []
merge [] (y:ys) = 0 : y : merge [] ys
merge _ _ = []
When we have some elements on both sides, we take both of them. When one of elements is absent, we take 0 instead of it. In all other cases (it is the merge [] [] case) we end up with our recursion and return an empty list.
We can also slightly generalize our function to support any number-like type:
merge :: Num a => [a] -> [a] -> [a]
merge (x:xs) (y:ys) = x : y : merge xs ys
merge (x:xs) [] = x : 0 : merge xs []
merge [] (y:ys) = 0 : y : merge [] ys
merge _ _ = []
Also, we can go further and use def from Data.Default package to get the default value for our type, so we can use this function with not only lists of numbers:
import Data.Default
merge :: Default a => [a] -> [a] -> [a]
merge (x:xs) (y:ys) = x : y : merge xs ys
merge (x:xs) [] = x : def : merge xs []
merge [] (y:ys) = def : y : merge [] ys
merge _ _ = []
Using the idea from this answer of mine, using the transpose :: [[a]] -> [[a]] function,
interweaveWith :: a -> [a] -> [a] -> [a]
interweaveWith def xs ys =
-- 0 [1] [10,15,20] => [1,10,0,15,0,20]
concat $
zipWith const
(transpose [ xs ++ repeat def, -- no limit, padded with def
ys ++ repeat def ])
(transpose [xs, ys]) -- as long as the longest

Create a list of sublists of a given list

I need a function that returns a list of all possible sublists, without skipping elements, e.g. sublists [1,2,3,4] should return [[1,2,3,4],[1,2,3] etc.] but the list should NOT contain [1,2,4].
My current "solution" is
>sublists :: [Integer] -> [[Integer]]
>sublists [] = [[]]
>sublists (x:xs) = [x:ys | ys <- sublists xs] ++ sublists xs
which does include [1,2,4]
Thanks in advance
EDIT: Found a solution (with a little help of my friend)
Looks a bit clumsy but it works
>sublists :: [Integer] -> [[Integer]]
>sublists [] = [[]]
>sublists (x:xs) = subs [] (x:xs) ++ sublists xs
> where
> subs :: [Integer] -> [Integer] -> [[Integer]]
> subs xs [] = [xs]
> subs xs (a:as) = (xs ++ [a]) : (subs (xs ++ [a]) as)
Data.List contains both inits and tails. What you want is the inits of each member of the tails list (or possibly vice-versa, but see later for the reason why this way round is better)
sublists = concatMap inits . tails
> sublists [1,2,3,4]
[[],[1],[1,2],[1,2,3],[1,2,3,4],[],[2],[2,3],[2,3,4],[],[3],[3,4],[],[4],[]]
If you prefer, you might want to get rid of all the null lists:
sublists = filter (not . null) . concatMap inits . tails
Or if you prefer to avoid generating the null lists in the first place:
sublists = concatMap (tail . inits) . tails
The result of inits always starts with the empty list, while the result of tails always ends with the empty list. So tail . inits is safe because tail will never be applied to an empty list; it just returns the result without the leading empty list. inits [] just returns [[]], so the last empty list from tails gets dropped.

Finding the Highest number of two lists-haskell

merge :: [a] -> [a] -> [a]
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) = x : y : merge xs ys
maxOfTwoLists [x] [y] = maximum (merge [x] [y])
I am trying to combine the two lists then find the max value in the single list. It compiles but when i call maxOfTwoLists it gives me a non-exhaustive patterns error. My merge returns a single list just fine, and maximum takes a single list. So it feels like it should be working.
If you're looking to merge two lists, the builtin concat would help. It flattens a list, so we could do the following:
maxOfTwoLists :: (Ord a) => [a] -> [a] -> a
maxOfTwoLists xs ys = maximum $ concat [xs,ys]
In which, $ means to evaluate the result of the right side function before applying it to the left side function.
As #badcook notes the pattern match isn't quite right.
merge :: [a] -> [a] -> [a]
merge xs [] = xs
merge [] ys = ys
merge (x:xs) (y:ys) = x : y : merge xs ys
maxOfTwoLists :: (Ord a) => [a] -> [a] -> a
maxOfTwoLists [] ys = maximum ys
maxOfTwoLists xs [] = maximum xs
maxOfTwoLists xs ys = maximum (merge xs ys)
I'll guess you wrote the merge function as an exercise but you can also use ++ from Prelude to append one list to another.
maxOfTwoLists :: (Ord a) => [a] -> [a] -> a
maxOfTwoLists xs ys = maximum (xs ++ ys)
Output:
λ> maxOfTwoLists [1,2,3] [4,5,6]
6
λ> maxOfTwoLists [1,2,3] []
3
λ> maxOfTwoLists [] [1,2,3]
3
λ>