How to sum tuples in a list of tuples? - list

I have the following list for example:
example = [(5.4, 3.2), (2.4, 3.5), (2.4, 4.0), (5.1, 3.6)]
And I'd like to get the sum of each '()' tuple. It means that I'd like to sum 5.4 with 3.2, then 2.4 with 3.5 and so on.
The result should look like this:
First: 8.6
Second: 5.9
Third: 6.4
Fourth: 8.7
I could do it with one pair only, but don't know how to get each sum from the list.
sumexample:: [(Double, Double)] -> [Double]
sumexample [(a, b)] = a + b

So you wrote
sumexample :: [(Double, Double)] -> [Double]
sumexample [(a, b)] = [ a + b ]
-- ^^^ ^^^ -- (error, corrected)
Ah, great! You've already got all you need to solve it. Almost. The missing part is the appending operator ++, with which a list of any length can be built by appending the singleton lists of its elements:
[ 1, 2, 3, ... ] ===
[1] ++ [2] ++ [3] ++ ...
So then sumexampleList should follow the law of
sumexampleList :: [(Double, Double)] -> [Double]
sumexampleList [a , b , c , ... ] ===
sumexampleList ( [a] ++ [b] ++ [c] ++ ... ) ===
sumexample [a] ++ sumexample [b] ++ sumexample [c] ++ ... ===
sumexample [a] ++ sumexampleList [b, c, ... ]
-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ --- right?
Haskell doesn't understand the above as a valid definitional syntax though. But it does understand
[1, 2, 3, ...] ===
1 : [2, 3, ...]
and so we can re-write the above law in the conventional syntax as
sumexampleList (a : bcde) =
sumexample a ++ sumexampleList bcde
and that is a bona fide recursive function definition in Haskell.
One case is missing though, the one with the empty list, [].
You will need to complete the definition by adding that additional equation.
Having solved this, sumexample :: [(Double, Double)] -> [Double] is bad design: it only works with singletons, but the type is list. So do away with the brackets altogether:
sumexample :: (Double, Double) -> Double
sumexample (a, b) = ....
and amend the recursive definition accordingly.

Related

How do you convert a list of numbers into a list of ranges in haskell?

Say you have a list of numbers, [1,2,3,5,6,7,8,9,11,12,15,16,17]
and you want a function that takes that as an input and returns something like
[[1,3],[5,9],[11,12],[15,17]] or alternatively maybe
[(1,3), (5,9), (11,12), (15,17)]
how would this be done? all of the solutions i've found online are very very long and quite convoluted, when this seems like such an easy problem for a functional language like haskell
So we have a list of numbers,
xs = [1,2,3,5,6,7,8,9,11,12,14,16,17] -- 14 sic!
We turn it into a list of segments,
ys = [[x,x+1] | x <- xs]
-- [[1,2], [2,3], [3,4], [5,6], ..., [11,12], [12,13], [14,15], [16,17], [17,18] ]
we join the touching segments,
zs = foldr g [] ys
-- [[1,4], [5,10], [11,13], [14,15], [16,18]]
where
g [a,b] [] = [[a,b]]
g [a,b] r#([c,d]:t) | b==c = [a,d]:t
| otherwise = [a,b]:r
and we subtract 1 from each segment's ending value,
ws = [[a,b-1] | [a,b] <- zs]
-- [[1,3], [5,9], [11,12], [14,14], [16,17]]
All in all we get
ranges :: (Num t, Eq t) => [t] -> [[t]]
ranges = map (\[a,b] -> [a,b-1]) . foldr g [] . map (\x -> [x,x+1])
where
g [a,b] [] = [[a,b]]
g [a,b] r#([c,d]:t) | b==c = [a,d]:t
| otherwise = [a,b]:r
Simple and clear.
edit: or, to be properly lazy,
where
g [a,b] r = [a,x]:y
where
(x,y) = case r of ([c,d]:t) | b==c -> (d,t) -- delay forcing
_ -> (b,r)
update: as dfeuer notes, (a,a) type is better than [a,a]. Wherever [P,Q] appears in this code, replace it with (P,Q). This will improve the code, with zero cost to readability.
I would definitely prefer the alternative representation to the first one you give.
ranges :: (Num a, Eq a) => [a] -> [(a,a)]
ranges [] = []
ranges (a : as) = ranges1 a as
-- | A version of 'ranges' for non-empty lists, where
-- the first element is supplied separately.
ranges1 :: (Num a, Eq a) => a -> [a] -> [(a,a)]
ranges1 a as = (a, b) : bs
where
-- Calculate the right endpoint and the rest of the
-- result lazily, when needed.
(b, bs) = finish a as
-- | This takes the left end of the current interval
-- and the rest of the list and produces the right endpoint of
-- that interval and the rest of the result.
finish :: (Num a, Eq a) => a -> [a] -> (a, [(a, a)])
finish l [] = (l, [])
finish l (x : xs)
| x == l + 1 = finish x xs
| otherwise = (l, ranges1 x xs)
To solve the Rosetta Code problem linked in the comment above, this isn't really quite an optimal representation. I'll try to explain how to match the representation more precisely later.
So one might do it like the idea from #Will Ness on the stateful folding or mine under the same answer. All explanations are to be found there. Besides, if you get curious and want to read more about it then have a look at Haskell Continuation Passing Style page. I am currently trying to gerealize this in such a way that we can have a variant of foldr1 in a stateful manner. A foldS :: Foldable t => (a -> a -> b) -> t a -> b. However this is still not general stateful folding. It's just tailored to this question.
ranges :: (Ord a, Num a) => [a] -> [[a]]
ranges xs = foldr go return xs $ []
where
go :: (Ord a, Num a) => a -> ([a] -> [[a]]) -> ([a] -> [[a]])
go c f = \ps -> let rrs#(r:rs) = f [c]
in case ps of
[] -> [c]:r:rs
[p] -> if p + 1 == c then rrs else [p]:(c:r):rs
*Main> ranges [1,2,3,5,6,7,8,9,11,12,15,16,17]
[[1,3],[5,9],[11,12],[15,17]]
I haven't had time to test any edge cases. All advices are welcome.

How do I generate all combinations of list elements to a given length with iterate?

I'm trying to write a function using iterate which should generate all combinations of the elements:
f :: [a] -> [[[a]]]
f [1,2] =
[ [[1] , [2]] -- all combinations of length 1
, [[1,1],[1,2],[2,1],[2,2]], -- all combinations of length 2
, [[1,1,1],... ] -- all combinations of length 3
, ... -- and so on
] -- infinitely
I've tried the following approach
f :: [a] -> [[[a]]]
f list = iterate genLists list
genLists :: [a] -> [[a]]
genLists list = [ [k] | k<-list ]
However, Hugs gives me the following error:
Type error in application
*** Expression : iterate genLists list
*** Term : genLists
*** Type : [a] -> [[a]]
*** Does not match : [[a]] -> [[a]]
*** Because : unification would give infinite type
I don't really know why I get the error. Also, how can I generate those combinations using only iterate? I cannot import any other module since this is an assignment.
Lets see why you get the error:
iterate :: (a -> a ) -> a -> [a]
genLists :: [a] -> [[a]]
As you can see, iterate takes a function that takes and returns the same type. However, genLists doesn't do that. It takes a list and returns a list of lists.
Since you actually want f :: [a] -> [[[a]]], genLists return type is actually fine. However, its argument type is wrong. It has to be of type genLists :: [[a]] -> [[a]]:
f :: [a] -> [[[a]]]
f xs = iterate genLists [[x] | x <- xs]
where
genLists yss = [ x : ys | x <- xs , ys <- yss]
Here is one possible implementation, using the applicative style (which you can learn more about here).
import Control.Applicative
f :: [a] -> [[[a]]]
f xs = iterate genLists $ map pure xs
where
genLists xss = (:) <$> xs <*> xss
Then,
λ> take 3 $ f [1,2]
[[[1],[2]],[[1,1],[1,2],[2,1],[2,2]],[[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,1],[2,1,2],[2,2,1],[2,2,2]]]
Here is an alternative, if you don't want to or cannot use applicative stuff:
f :: [a] -> [[[a]]]
f xs = iterate genLists $ map (\x -> [x]) xs
where
genLists xss = [y : ys | y <- xs, ys <- xss]

Attaching list of tuples together

I have a list of tuples which looks like this in Haskell:
([],[[]],[])
And I want to perform some operations on these lists and return all possible changes of state onto them. I want to return a list of this tuple and I am not quite sure how to bind them together. When I tried cons or ++ I get some errors.
([],[[]],[]):([],[[]],[])
([],[[]],[])++([],[[]],[])
<interactive>:81:1:
Couldn't match expected type ‘[a]’
with actual type ‘([t0], [t1], [t2])’
Relevant bindings include it :: [a] (bound at <interactive>:81:1)
In the first argument of ‘(++)’, namely ‘([], [], [])’
In the expression: ([], [], []) ++ ([], [], [])
In an equation for ‘it’: it = ([], [], []) ++ ([], [], [])
your main problem here is that you have an tuple of lists instead of a list of tuples as you claimed - so of course neither : nor ++ will work.
Maybe you want to use those operations component-wise, which can be done by something like:
map3 :: (a -> b -> c) -> (a, a, a) -> (b, b, b) -> (c, c, c)
map3 op (xs,ys,zs) (xs',ys',zs') = (xs `op` xs',ys `op` ys',zs `op` zs')
using this you get:
λ> map3 (++) ([],[[]],[]) ([],[[]],[])
([],[[],[]],[])
λ> map3 (:) ([],[[]],[]) ([],[[]],[])
([[]],[[[]],[]],[[]])
if this is not what you expected / wanted then please add an example on what you want

Adding something to the beginning of a list with ':' operator in Haskell

I started studying Haskell few days ago, went through the basics and there's a few things left that I can't make sense of.
First of all,
when I try to add something to the beginning of a list with the ':' operator in a GHCi console, it works only if I try to add single literals, but not lists. (5:[1,2,3,4]) would work but ([1,2]:[3,4,5]) would not. However there's this function:
replicate2 n x
| n <= 0 = []
| otherwise = x:replicate2 (n-1) x
As i understand this how it works recursively, let's call replicate2 2 [1,2]:
it will slip through the first guard and hence:
= [1,2]:replicate (2-1) [1,2]
= [1,2]:[1,2]:replicate (1-1) [1,2]
-- since n is now 0 it's an edge condition and first guard returns [], so recursion ends and we get:
= [1,2]:[1,2]:[]
and the function returns [[1,2],[1,2]]
My question: How does this work? Shouldn't Haskell be mad and spit out errors? It does when I try to do that in GHCi.
Well, let's review some things. the principal (= most general) type of the : operator is this:
(:) :: a -> [a] -> [a]
a is a type variable. What this whole thing means is that every time the operator is actually used, the context of its usage determines what type a will stand for in that particular use. So if you're doing this:
example1 :: [Integer]
example1 = 5 : [1, 2]
...in that context a is Integer, and if you're doing this:
example2 :: [[Integer]]
example2 = [1,2] : [[1,2]]
...then in that context a is [Integer]. So what the type means:
(:) :: a -> [a] -> [a]
...is that the type a of the value you're putting at the head of the list must be the same as the type of the values that go into that list. If it's a list whose elements are Integers then the value must be an Integer as well. And in the example that's confusing you, we have a list of lists of Integers, so the first argument of : in that context is a list of Integer.
Haskell is very precise about this, so we could keep going with other examples illustrating the same principle. Here for example we put a list of lists in front of a list of lists of lists:
example3 :: [[[Integer]]]
example3 = [[1, 2], [3, 4]] : [[[1, 2]]]
-- Value: [[[1, 2], [3, 4]], [[1, 2]]]
So going again to the principal type of ::
(:) :: a -> [a] -> [a]
Another way of looking at it is as a pattern that all of the uses of : must obey: the type of the first argument must have one pair of square brackets fewer than the types of the second argument and the result. Another thing it tells us is that : doesn't care about what type a may be—it could be a simple value like Integer, or it could be some complex thing like [[[[Integer]]]], and this function just can't tell the difference.
My Question: How does this work? I don't understand why because it should not.
You're wrong in that it should not, and you're wrong because you forgot that a might as well mean [a].
Let's look at some type equations:
[] :: [a]
(:) :: a -> [a] -> [a]
[1,2,3] :: [Int]
0 : [1,2,3] :: [Int]
Now with a twist:
[] :: [[a]]
(:) :: [a] -> [[a]] -> [[a]]
[[1,2], [3]] :: [[Int]]
[0] : [[1,2], [3]] :: [[Int]]
A list of lists is still a list, of which an element appended by : is... a list.

removing tuples from list (Haskell)

I want to write a function that takes as argument a list of tuples like this:
remove' [ ("a", True), ("b", False), ("c", False), ("d", True) ]
I would like to return a list of tuples that have False as their second value, so I'd like my function to return
[ ("b", False), ("c", False) ]
Here's what I have so far but it won't load in GHCi. can anyone help me out? Thanks
remove' :: [(a,b)] -> [(a,b)]
remove' [(a,b)] = [ c | c <- [(a,b)], c `notElem` True ]
Since you want to match the second element of the tuples, you need to pick the second element from the tuple and compare it with False like this
remove' :: [(a, Bool)] -> [(a, Bool)]
remove' xs = [c | c <- xs, snd c == False]
The snd function will get second element from each of the tuples and compare them with False. Only if they match, they will be gathered in the resulting list.
Since the second elements are booleans, you can make use of the not function like this
[c | c <- xs, (not . snd) c]
We can express the same wihtout the dot notation like this
[c | c <- xs, not(snd(c))]
Note: In your program, you have
remove' [(a,b)] = ...
it means that, it will be executed only when remove is called with a list of tuples of size 1. You can check that like this
remove' :: [(a, Bool)] -> [(a, Bool)]
remove' [(a, b)] = [(a, b)]
remove' [ ("a", True), ("b", False), ("c", False), ("d", True) ]
will print
Non-exhaustive patterns in function remove'
It means the patterns you specified in the function definition is not covering all the possible inputs. Since we need process a list of tuples of any length, we accept it in xs and use it in the List Comprehension.
I'm surprised no one has yet said
remove' = filter (not . snd)
You just need filter and select second item in lambda:
filter (\x -> (snd x) == False) [("a", False), ("b", True)]
Response:
[("a",False)]