Haskell:create list of last elements of each list in list - list

I need to define the function in Haskell's
which for a given list of lists will create a list of its last elements.
For example for [[1,2],[3,4]] it should return [2,4]
I tried to use pattern matching but ite returns only the last list :
lastElement :: [[a]] -> [a]
lastElement [] = error "error"
lastElement [x] = x
lastElement (x:xs) = lastElement xs
it gives me [3,4]

Problem
You are on the right track, the problem is that your code is not recursing. A recursive function on lists is usually of the form
f :: [a] -> [b]
f [] = y
f (x:xs) = y : f xs
After y is evaluated, that result is ":ed" to the recursive call. Now try to make your code so something similar. Also note that you don't need the lastElement [x] case, it's just plain reduntant for the recursion. However, this only applies some function to every element. You will also need a function f :: [a] -> a to get that last element from one single list. Your function as of now does just that, but there is a standard library function for that. Have a look at Hoogle: you can search library functions by type or description
Better Alternative
In this case, I would use a list comprehension as I think it would be more clear to read. Have a look at that as well
Best Alternative
Haskell being a functional language, it allows you to think more about what change to need to apply to your data, rather than what steps do you need to achieve. If you know them, you can use higher order function for this. In particular, the function map :: (a -> b) -> [a] -> [b]. As you can guess from this type definition, map takes a function, and applies it to every element of a list. It looks like you already know the last function, so you can use that:
lastElements :: [[a]] -> [a]
lastElements = map last
Look how neat and simple this code is now; no need to think about what the recursion does, you just see that it takes the last element from each list.

I will assume that you have beginner skills in Haskell and try to explain better what you are doing wrong.
lastElement :: [[a]] -> [a]
lastElement [] = error "error"
lastElement [x] = x
lastElement (x:xs) = lastElement xs
In this function, you are receiving a list of elements and returning the last of it. Occurs that those elements are lists too. In that way, applying lastElement [[1,2],[3,4]] will give to you his last element how is the list [3,4]. Since you need to enter a list [x,y,z] in which x y and z are lists and you wanna return [last of x, last of y, last of z], we need two things:
1. A function which receives a list of Int and return his last element
2. Apply this function to a (list of (lists of a)) [[a]]
To make (1) we can easily modify your function lastElement just like this:
lastElement :: [a] -> a
lastElement [] = error "error"
lastElement [x] = x
lastElement (x:xs) = lastElement xs
Now, lastElement receives one list and return its last element.
To make (2) we just need to create a mapping function like this:
mapping :: ([a] -> a) -> [[a]] -> [a]
mapping _ [] = []
mapping f (x:xs) = (f x) : (mapping f xs)
In that way, you can call mapping lastElement [[1,2],[3,4]] that will give you [2,4].
I need to say that none of this is needed if you knew two functions which is last who do the same as (1) and map who do the same as (2). Knowing this, you can do like Lorenzo already done above:
lastElements :: [[a]] -> [a]
lastElements = map last

Related

Haskell list to unitary sublist

I'm having problems turning a list to a unitary sublist
sublists :: [a] -> [[a]]
sublists [] = [[]]
sublists (x:xs) = [x:ys | ys <- sub] ++ sub
where sub = sublists xs
I need a function that given
sublists [True,False]
returns
[[True],[False]] instead of [[True,False],[True],[False],[]]
But I just donĀ“t know how and feel like punching my computer in the face.
I hope I am clear. Thanks!
So you want a function that converts a to [a]. Okay...
makeList = \x -> [x]
(why did I write it as a lambda? keep reading)
So you want a function that converts a to [a] within a list. Okay...
makeListsInList = map (\x -> [x])
done.
You can use the function pure :: Applicative f => a -> f a to wrap values into a list, since the instance of Applicative for [] wraps elements in a singleton list.
So you can define your function as:
sublists :: [a] -> [[a]]
sublists = map pure
For example:
Prelude> sublists [True, False, False, True]
[[True],[False],[False],[True]]

Haskell -- Sums Accumulated in Lists

I need to create or know if there is a function in Haskell that allows you to add items from a list. So, for example:
cumulativeAmount :: [Integer] -> [Integer]
cumulativeAmount [1,2,5,8,8,0,4,2] = [1,3,8,16,24,24,28,30]
cumulativeAmount [1,4,7,0,5] = [1, 1+4, 1+4+7, 1+4+7+0, 1+4+7+0+5] = [1,5,12,12,17]
I tried to use the map and scanl function, but I didn't get what I wanted, because I added all the elements.
This is exactly the purpose of scanl1 :: (a -> a -> a) -> [a] -> [a]:
Prelude> scanl1 (+) [1,2,5,8,8,0,4,2]
[1,3,8,16,24,24,28,30]
scanl1 takes as input a function f :: a -> a -> a (here (+)), and a list of as. It constructs a list where the first item is the first item of the list. This is the first value of the accumulator. Then for every value, the accumulator is updated by calling f with the accumulator and the next value of the list, this item is then yielded.
So in case of scal1 (+) [1,2,5] the first item we emit is 1, we also set the accumulator to 1. The next item is 2, so we call (+) 1 2 (which is 3) and this is the result and the new accumulator, next we call (+) ((+) 1 2) 5 (which is 8), etc.
But I think it is better, as an exercise to use recursion. Like said before we use an accumulator. We can implement this by introducing an extra function where the accumulator is a function we pass through the recursive calls (and update). So in that case it looks like:
cumulativeAmount :: [Integer] -> [Integer]
cumulativeAmount [] = ...
cumulativeAmount (x:xs) = go x xs
where go x xs = ...
so here the first argument of go (x) is the accumulator. I leave it as an exercise to implement it with recursion.
What about using an accumulator:
cumulativeAmount :: (Num a) => [a] -> [a]
cumulativeAmount xs = go xs 0
where go [] acc = []
go (x:xs) acc = (acc+x) : go xs (acc+x)
Which works as follows:
*Main> cumulativeAmount [1,2,5,8,8,0,4,2]
[1,3,8,16,24,24,28,30]
The above code keeps a state variable acc to accumulate sums whenever a new number is encountered, and adds the new sum to the resulting list.
Now a good exercise would be to replace the above code with higher order functions.
Off the top of my head, you could solve this with a list comprehension, like so:
cumulativeAmount xs = [ sum $ take x xs | x <- [1..length xs] ]

Creating a lists of lists with new element in each position

i'm new in the haskell world and i'd like to know how to insert a value in each position of a list in haskell, and return a lists of sublists containing the value in each position. For example:
insert' :: a -> [a] -> [[a]]
insert' a [] = [[a]]
insert' a list = ??
To get something like:
insert' 7 [1,2,3] = [[7,1,2,3],[1,7,2,3],[1,2,7,3],[1,2,3,7]]
insert' :: a -> [a] -> [[a]]
insert' y [] = [[y]]
insert' y xss#(x:xs) = (y : xss) : map (x :) (insert' y xs)
While the empty list case comes natural, let's take a look at insert' y xss#(x:xs). We essentially have two cases we need to cover:
y appears in front of x. Then we can just use y : xss.
y appears somewhere after x. We therefore just insert it in the rest of our list and make sure that x is the first element with map (x:).
Although #delta's answer is definitely more elegant, here a solution with difference lists. If we insert an element x on every location of list ys = [y1,y2,...,yn], the first time we will insert it as head, so that means we can construct x : ys.
. For the second element of the resulting list, we want to construct a list [y1,x,y2,...,yn]. We can do this like y1 : x : y2s. The next lists will all have a structure y1 : ....
The question is: how can we write a recursive structure that keeps track of the fact that we want to put elements in the head. We can use a function for that: we start with a function id. If we now call id (x:ys) then we will of course generate the list (x:ys).
We can however, based on the id function, construct a new function id2 = \z -> id (y1:z). This function will thus put y1 in the head of the list and then add the list with which we call id2 as tail. Next we can construct id3 = \z -> id2 (y2:z). This will put y1 and y2 as first elements followed by the tail z.
So we can put this into the following recursive format:
insert' :: a -> [a] -> [[a]]
insert' x = go id
where go d [] = [d [x]]
go d ys#(yh:yt) = (d (x : ys)) : go (d . (yh :)) yt
So we redirect insert' to go where the initial difference list is simply the id function. Each time we check if we have reached the end of the given list. If that is the case, we return the basecase: we call [x] (as tail) on the difference list, and thus construct a list where we append x as last element.
In case we have not yet reached the last element, we will first emit d (x : ys): we prepend x to the list and provide this as argument to the difference list d. d will prepend y1 : y2 : ... : yk up to the point where we insert x. Furthermore we call recursively go (d . (yh :)) yt on the tail of the list: we thus construct a new difference list, wehere we insert (yh :) as tail of the list. We thus produce a new function with one argument: the tail after the yh element.
This function produces the expected results:
*Main> insert' 4 []
[[4]]
*Main> insert' 4 [1,2,5]
[[4,1,2,5],[1,4,2,5],[1,2,4,5],[1,2,5,4]]
*Main> insert' 7 [1,2,3]
[[7,1,2,3],[1,7,2,3],[1,2,7,3],[1,2,3,7]]
You may also do as follows;
import Data.List
spread :: a -> [a] -> [[a]]
spread x xs = zipWith (++) (inits xs) ((x:) <$> tails xs)
*Main> spread 7 [1,2,3]
[[7,1,2,3],[1,7,2,3],[1,2,7,3],[1,2,3,7]]
*Main> spread 7 []
[[7]]
So this is about three stages.
(x:) <$> tails xs is all about applying the (x:) function to all elements of tails xs function. So tails [1,2,3] would return [[1,2,3],[2,3],[3],[]] and we are to apply an fmap which is designated by <$> in the inline form. This is going to be the third argument of the zipWith function.
(inits xs) which would return [[],[1],[1,2],[1,2,3]], is going to be the second argument to zipWith.
zipWith (++) is obviously will zip two list of lists by concatenating the list elements.
So we may also express the same functionality with applicative function functors as follows;
spread :: a -> [a] -> [[a]]
spread x = zipWith (++) <$> inits <*> fmap (x:) . tails
In this case we fmap the zipWith (++) function with type [[a]] -> [[a]] -> [[a]] over inits and then apply it over to fmap (x:) . tails.
It could get more pointfree but becomes more complicated to read through (at least for me). In my opinion this is as best as it gets.

Inverting List Elements in Haskell

I am trying to invert two-elements lists in xs. For example, invert [[1,2], [5,6,7], [10,20]] will return [[2,1], [5,6,7], [20,10]]. It doesn't invert [5,6,7] because it is a 3 element list.
So I have written this so far:
invert :: [[a]] -> [[a]]
invert [[]] = [[]]
which is just the type declaration and an empty list case. I am new to Haskell so any suggestions on how to implement this problem would be helpful.
Here's one way to do this:
First we define a function to invert one list (if it has two elements; otherwise we return the list unchanged):
invertOne :: [a] -> [a]
invertOne [x, y] = [y, x]
invertOne xs = xs
Next we apply this function to all elements of an input list:
invert :: [[a]] -> [[a]]
invert xs = map invertOne xs
(Because that's exactly what map does: it applies a function to all elements of a list and collects the results in another list.)
Your inert function just operations on each element individually, so you can express it as a map:
invert xs = map go xs
where go = ...
Here go just inverts a single list according to your rules, i.e.:
go [1,2] = [2,1]
go [4,5,6] = [4,5,6]
go [] = []
The definition of go is pretty straight-forward:
go [a,b] = [b,a]
go xs = xs -- go of anything else is just itself
I would do this:
solution ([a,b]:xs) = [b,a] : solution xs
solution (x:xs) = x : solution xs
solution [] = []
This explicitly handles 2-element lists, leaving everything else alone.
Yes, you could do this with map and an auxiliary function, but for a beginner, understanding the recursion behind it all may be valuable.
Note that your 'empty list case' is not empty. length [[]] is 1.
Examine the following solution:
invert :: [[a]] -> [[a]]
invert = fmap conditionallyInvert
where
conditionallyInvert xs
| lengthOfTwo xs = reverse xs
| otherwise = xs
lengthOfTwo (_:_:_) = True
lengthOfTwo _ = False

How to recursively call a function over the length of the list?

I had an interview question, and it has been bugging me since then.
I have a function, fill, that does the computation like taking two lists and then replacing 2s in the second list, where ever there are 2s in the first list and also once 2s are filled in the second list from the first list, then it can flow till a 1 is encountered. For eg:
Two lists [2,1,2,1,2] [0,0,1,0,0] is passed, so the output I get is [2,2,1,2,2]. Now, I want to write a function that takes an argument something like this: [[2,1,2,1,2],[0,0,1,0,0],[0,0,0,0,0]], I want to apply my above function recursively till the end of this list of lists. So like first [2,1,2,1,2] [0,0,1,0,0] are passed to fill, then it should get the result [2,2,1,2,2], then [2,2,1,2,2] and [0,0,0,0,0] should be passed, getting the result [2,2,2,2,2]. How can I do that?
EDIT:
I did this:
fillAll::[[Int]]->[Int]
fillAll [] = []
fillAll (x:xs) =
(foldl' seep x xs) $
helper2 x
helper2:: [Int] -> Bool
helper2 lst =
if 2 `elem` lst then True else False
So, you have your function fill:
fill :: [Int] -> [Int] -> [Int]
And you want to turn this into a function which takes a list of lists:
fillRec :: [[Int]] -> [Int]
This is a natural case for a fold. This repeatedly 'folds' each element of a list together using a combining function. We need to make sure the list isn't empty:
fillRec [] = []
fillRec (x : xs) = foldl fill x xs
This version of foldl (e.g. folds from the left, rather than from the right) is non-strict, which can cause large memory accumulation. It's better to use the strict variant foldl' from Data.List:
fillRec (x : xs) = foldl' fill x xs
I'm going to assume that you already have fill :: [Int] -> [Int] -> [Int] defined. If so, this problem is pretty easy to solve using a fold. Explicitly, you could do something like
fillAll :: [[Int]] -> [Int]
fillAll [] = []
fillAll (x:xs) = go x xs
where
go first [] = first
go first (second:rest) = go (fill first second) rest
Or you can use one of the built-in folds:
fillAll [] = []
fillAll (x:xs) = foldl fill x xs
but as Impredicative points out, you'll have better performance with foldl' from Data.List