I am still not into Haskell and need a hint for the following function.
I want to create a list by adding each multiplication of a pair:
all :: Int -> (Int,Int) -> [(Int, Int)]
all n, pair = ...
E.g. n = 3, pair (1,2) => [(1,2), (2,4), (3,6)]
which expands to [(1*(1,2)), ((2*(1,2)), (3*(1,2))]
I know its something with x <- [1..n] and x*pair but I don't know which built-in function is right to put it together!
You need to do the multiplication separately on the elements in the tuples, and then recreate a tuple. You can use fst and snd to get the elements.
all n pair = [(x*(fst pair), x*(snd pair)) | x <- [1..n]]
Pattern matching is another common way to access tuple elements.
all n (a, b) = [(x*a, x*b) | x <- [1..n]]
Related
So I already have a function that finds the number of occurrences in a list using maps.
occur :: [a] -> Map a a
occur xs = fromListWith (+) [(x, 1) | x <- xs]
For example if a list [1,1,2,3,3] is inputted, the code will output [(1,2),(2,1),(3,2)], and for a list [1,2,1,1] the output would be [(1,3),(2,1)].
I was wondering if there's any way I can change this function to use foldr instead to eliminate the use of maps.
You can make use of foldr where the accumulator is a list of key-value pairs. Each "step" we look if the list already contains a 2-tuple for the given element. If that is the case, we increment the corresponding value. If the item x does not yet exists, we add (x, 1) to that list.
Our function thus will look like:
occur :: Eq => [a] -> [(a, Int)]
occur = foldr incMap []
where incMap thus takes an item x and a list of 2-tuples. We can make use of recursion here to update the "map" with:
incMap :: Eq a => a -> [(a, Int)] -> [(a, Int)]
incMap x = go
where go [] = [(x, 1)]
go (y2#(y, ny): ys)
| x == y = … : ys
| otherwise = y2 : …
where I leave implementing the … parts as an exercise.
This algorithm is not very efficient, since it takes O(n) to increment the map with n the number of 2-tuples in the map. You can also implement incrementing the Map for the given item by using insertWith :: Ord k => (a -> a -> a) -> k -> a -> Map k a -> Map k a, which is more efficient.
dobb[] = []
dobb (x:xs) = [x * 2| x<- xs]
I am really new to haskell and started learning it this week. I want to create a function that multiplies each element in a list by 2. So the list would go from [1,2,3] to [2,4,6]. The code I have works fine, except it skips the first element of the list and goes from [1,2,3] to [4,6]. How can I make the code multiply the first element as well?
[x*2 | x<-[1..5]]
I've found this line that does what I am looking for, but I dont understand how to go from this line of code and convert it to a function that works for all lists.
I'll address your last question,
how to go from this line of code,
[x*2 | x <- [1..5]]
and convert it to a function that works for all lists[?]
This is known as generalization and is achieved by abstraction. First we name it,
foo = [x*2 | x <- [1..5]]
then we name that arbitrary piece of data we used as an example to work on,
foo = let {xs = [1..5]} in [x*2 | x <- xs]
and then we abstract over it by removing that arbitrary piece of data in the internal definition, letting it become the function parameter instead, to be specified by this, now, function's callers:
foo xs = [x*2 | x <- xs]
and there it is, the general function working on all lists, doing the same thing as it did on the specific example we used at first.
If you use the pattern (x:xs) then you unpack the list such that x is the head (first item) of the list, and xs is the tail (remaining items) of that list. For a list [1,4,2,5], x will thus refer to 1, and xs to [4,2,5].
In the list comprehension, you then use x <- xs as a generator, and thus you enumerate over the remaining elements. The x in the list comprehension is furthermore not the head of the list, but a more locally scoped variable.
You can work with list comprehension and work on the entire list, so:
dobb :: Num a => [a] -> [a]
dobb xs = [x * 2| x <- xs]
We can also work with map :: (a -> b) -> [a] -> [b] to perform the same operation on the elements:
dobb :: Num a => [a] -> [a]
dobb = map (2*)
I want to create a function that rearranges the elements of a list.
For example the list [1,2,3] will produce:
[1,2,3]
[1,3,2]
[2,1,3]
[2,3,1]
[3,1,2]
[3,2,1]
The order isn't important.
If I write this list comprehension:
[[a,b,c] | a <- l, b <- l, c <- l, a /= b, a /= c, b /= c]
It works (where l is the desired list). Problem is I want to do this for an undefined number of list elements
Yes. The Data.List module has a permutations :: [a] -> [[a]] function to generate all permutations. This does not only work on three or more elements, but it does not use an Eq typeconstraint. If a list contains two items that are equal, then you can still consider it a different permutation when we swap the two.
We can furthermore implement such function ourself. We can first make a helper function that is given a list and returns a list of 2-tuples where the first item contains the value we "picked", and the second item a list of remaining elements:
pick :: [a] -> [(a, [a])]
pick [] = []
pick (x:xs) = (x, xs) : map prep (pick xs)
where prep (y, ys) = (y, x:ys)
For example:
Prelude> pick [1,4,2,5]
[(1,[4,2,5]),(4,[1,2,5]),(2,[1,4,5]),(5,[1,4,2])]
Next we can use recursion to each time pick an element, and recurse on the remaining elements:
perms :: [a] -> [[a]]
perms [] = [[]]
perms xs = [ p : ps | (p, ys) <- pick xs, ps <- perms ys ]
This then yields:
Prelude> perms [1,4,2,5]
[[1,4,2,5],[1,4,5,2],[1,2,4,5],[1,2,5,4],[1,5,4,2],[1,5,2,4],[4,1,2,5],[4,1,5,2],[4,2,1,5],[4,2,5,1],[4,5,1,2],[4,5,2,1],[2,1,4,5],[2,1,5,4],[2,4,1,5],[2,4,5,1],[2,5,1,4],[2,5,4,1],[5,1,4,2],[5,1,2,4],[5,4,1,2],[5,4,2,1],[5,2,1,4],[5,2,4,1]]
How can I define a function in Haskell, which gets a list of lists of doubles, and return the highest value of each list using map?
Like this: func4 [[2,4],[4,7],[7,9]] = [4,7,9].
I tried to do it in many ways, but it goes wrong. Is it possible to perform this operation?
func4 [[x,y]] = map maximum [x,y]
and
func4 [[x,y]] = [xs| xs <- map maximum [x,y]]
The reason it does not work is because func4 expects - as you say yourself - a list of lists. So [[x,y]] is a list of lists. Now that means that [x,y] is a list of items. You cannot know for sure that x and y are lists themselves where you can calculate the maximum from (and even if that works, it is not correct).
you can simply omit the [[x,y]] pattern and use l (the list of lists), like:
func4 :: Ord b => [[b]] -> [b]
func4 l = map maximum l
Or even better, use eta-reduction:
-- with eta-reduction
func4 :: Ord b => [[b]] -> [b]
func4 = map maximum -- look mom... no variables
If it is a requirement that every list contains exactly two elements, you can also use:
func4 :: Ord b => [[b]] -> [b]
func4 = map (\[x,y] -> max x y)
Here you do pattern matching on the item, and it must be a list with two elements x and y you then map on the max x y. This function will error if it has to map a list not containing exactly two elements. The \[x,y] -> max x y is called a lambda expression.
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?).