Haskell foldr with multiplication - haskell

I'm supposed to write a function that will contain the product of each previous multiplication with that number
Basically this:
> productFromLeftToRight [2,3,4,5]
[120,60,20,5]
I'm supposed to use High Order functions, so folds and such. I'm thinking of using a foldr to traverse through the list with a lambda expression. This is what I'm thinking:
> productFromLeftToRight nums = foldr (\x acc -> [x] * acc ++ acc) [] nums
Since it would unravel like f(2 (f 3 (f 4 (f 5 [])))) I would think I'm right, but I get the whole print error and I don't know how to multiply a number with the first element of acc ( head acc doesn't work)

productFromLeftToRight = scanr1 (*)
or
productFromLeftToRight' =
snd . foldr (\x (acc,lst) -> (x * acc, x * acc : lst)) (1,[])

productFromLeftToRight nums =
init $ foldr (\x lst -> x * head lst : lst) [1] nums
The idea is to use a dummy element 1 to the answer list and remove it in the end.

Here's another one that doesn't do any post-processing after the foldr:
productFromLeftToRight = foldr (\n ps -> n * foldr const 1 ps : ps) []
Here, the inner foldr const 1 is acting as a non-partial head function to get the first element of ps:
foldr const 1 (x:xs) = const x (foldr const 1 xs) = x
foldr const 1 [] = 1

Related

Implementing tail recursion

I've written a simple function in haskell that is non tail recursive that sums up the values inside a list where:
nonTailRecursiveSum :: [Integer] -> Integer
nonTailRecursiveSum [] = 0 --base case
nonTailRecursiveSum (x:xs) = x + sum xs
But what I'm trying to do now is to implement the same function but using tail recursion. For what i know, tail recursion performs the recursive call at the final step so i tried something like:
tailRecursiveSum :: [Integer] -> Integer
tailRecursiveSum [] = 0
tailRecursiveSum (x:xs) = aux_f(x) + tailRecursiveSum xs
.
.
But i got lost in the midway as I'm not familiar with tail recursion in Haskell. Could anyone assist me on the continuation of the tail recursive version of the code?
Playing with it for a bit,
sum (x:y:xs) = x + sum (y:xs)
= x + (y + sum xs)
= (x + y) + sum xs
g a b = a + sum b
sum (x:y:xs) = g x (y:xs)
= x + g y xs
= g (x+y) xs -- !!!
the last one is in tail recursive form! We thus just define
sum xs = g 0 xs
where
g acc [] = ...
g acc (x:xs) = g (acc + ...) ...
Fill in the blanks!

How does the definition of scanr in terms of foldr work?

Exercise 1 at page 102 of the Haskell Wikibook asks "Write your own definition of scanr, first using recursion, and then using foldr." I wrote a recursive one:
myscan f acc [] = [acc]
myscan f acc (x:xs) = val : rest where
val = f x (head rest)
rest = myscan f acc xs
...but couldn't figure out a foldr version. I eventually Googled and found this answer:
myscan2 f acc xs = foldr f' [acc] xs where
f' x xs = (f x (head xs)) : xs
Obviously it works but it doesn't make sense to me. Using parameters
(+) 0 [1,2,3]
...it becomes something like this:
myscan2 (+) 0 [1,2,3] = foldr f' [0] [1,2,3] where
f' [0] [1,2,3] = ((+) [0] (head [1,2,3])) : [1,2,3]
...but ((+) [0] (head [1,2,3])) part is not type compatible for (+). Yet, the function works, so what am I reading or converting incorrectly?
The matter on the function you found is:
The xs on myscan2 f acc xs = foldr f' [acc] xs is not the same on
f' x xs = (f x (head xs)) : xs.
They are completly diferent. Maybe you could understand better if it looks like:
myscanr f acc xs = foldr f' [acc] xs
where f' b a = (f b (head a)) : a
What it does, change the accumulator to a list, because scanl accumlate but it keep all the path going through the original list. So, f' cons (:) a new head applying the function f to the actual element of the list and the head of accumulator.

Haskell, Foldr, and foldl

I've been trying to wrap my head around foldr and foldl for quite some time, and I've decided the following question should settle it for me. Suppose you pass the following list [1,2,3] into the following four functions:
a = foldl (\xs y -> 10*xs -y) 0
b = foldl (\xs y -> y - 10 * xs) 0
c = foldr (\y xs -> y - 10 * xs) 0
d = foldr (\y xs -> 10 * xs -y) 0
The results will be -123, 83, 281, and -321 respectively.
Why is this the case? I know that when you pass [1,2,3,4] into a function defined as
f = foldl (xs x -> xs ++ [f x]) []
it gets expanded to ((([] ++ [1]) ++ [2]) ++ [3]) ++ [4]
In the same vein, What do the above functions a, b, c, and d get expanded to?
I think the two images on Haskell Wiki's fold page explain it quite nicely.
Since your operations are not commutative, the results of foldr and foldl will not be the same, whereas in a commutative operation they would:
Prelude> foldl1 (*) [1..3]
6
Prelude> foldr1 (*) [1..3]
6
Using scanl and scanr to get a list including the intermediate results is a good way to see what happens:
Prelude> scanl1 (*) [1..3]
[1,2,6]
Prelude> scanr1 (*) [1..3]
[6,6,3]
So in the first case we have (((1 * 1) * 2) * 3), whereas in the second case it's (1 * (2 * (1 * 3))).
foldr is a really simple function idea: get a function which combines two arguments, get a starting point, a list, and compute the result of calling the function on the list in that way.
Here's a nice little hint about how to imagine what happens during a foldr call:
foldr (+) 0 [1,2,3,4,5]
=> 1 + (2 + (3 + (4 + (5 + 0))))
We all know that [1,2,3,4,5] = 1:2:3:4:5:[]. All you need to do is replace [] with the starting point and : with whatever function we use. Of course, we can also reconstruct a list in the same way:
foldr (:) [] [1,2,3]
=> 1 : (2 : (3 : []))
We can get more of an understanding of what happens within the function if we look at the signature:
foldr :: (a -> b -> b) -> b -> [a] -> b
We see that the function first gets an element from the list, then the accumulator, and returns what the next accumulator will be. With this, we can write our own foldr function:
foldr :: (a -> b -> b) -> b -> [a] -> b
foldr f a [] = a
foldr f a (x:xs) = f x (foldr f a xs)
And there you are; you should have a better idea as to how foldr works, so you can apply that to your problems above.
The fold* functions can be seen as looping over the list passed to it, starting from either the end of the list (foldr), or the start of the list (foldl). For each of the elements it finds, it passes this element and the current value of the accumulator to what you have written as a lambda function. Whatever this function returns is used as the value of the accumulator in the next iteration.
Slightly changing your notation (acc instead of xs) to show a clearer meaning, for the first left fold
a = foldl (\acc y -> 10*acc - y) 0 [1, 2, 3]
= foldl (\acc y -> 10*acc - y) (0*1 - 1) [2, 3]
= foldl (\acc y -> 10*acc - y) -1 [2, 3]
= foldl (\acc y -> 10*acc - y) (10*(-1) - 2) [3]
= foldl (\acc y -> 10*acc - y) (-12) [3]
= foldl (\acc y -> 10*acc - y) (10*(-12) - 3) []
= foldl (\acc y -> 10*acc - y) (-123) []
= (-123)
And for your first right fold (note the accumulator takes a different position in the arguments to the lambda function)
c = foldr (\y acc -> y - 10*acc) 0 [1, 2, 3]
= foldr (\y acc -> y - 10*acc) (3 - 10*0) [1, 2]
= foldr (\y acc -> y - 10*acc) 3 [1, 2]
= foldr (\y acc -> y - 10*acc) (2 - 10*3) [1]
= foldr (\y acc -> y - 10*acc) (-28) [1]
= foldr (\y acc -> y - 10*acc) (1 - 10*(-28)) []
= foldr (\y acc -> y - 10*acc) 281 []
= 281

Double every other element of list from right in Haskell

I have a list and I want to double every other element in this list from the right.
There is another related question that solves this problem but it doubles from the left, not the right: Haskell: Double every 2nd element in list
For example, in my scenario, [1,2,3,4] would become [2,2,6,4], and in that question, [1,2,3,4] would become [1,4,3,8].
How would I implement this?
I think that the top answer misinterpreted the question. The title clearly states that the OP wants to double the second, fourth, etc. elements from the right of the list. Ørjan Johansen's answer is correct, but slow. Here is my more efficient solution:
doubleFromRight :: [Integer] -> [Integer]
doubleFromRight xs = fst $ foldr (\x (acc, bool) ->
((if bool then 2 * x else x) : acc,
not bool)) ([], False) xs
It folds over the list from the right. The initial value is a tuple containing the empty list and a boolean. The boolean starts as false and flips every time. The value is multiplied by 2 only if the boolean is true.
OK, as #TomEllis mentions, everyone else seems to have interpreted your question as about odd-numbered elements from the left, instead of as even-numbered from the right, as your title implies.
Since you start checking positions from the right, there is no way to know what to double until the end of the list has been found. So the solution cannot be lazy, and will need to temporarily store the entire list somewhere (even if just on the execution stack) before returning anything.
Given this, the simplest solution might be to just apply reverse before and after the from-left solution:
doubleFromRight = reverse . doubleFromLeft . reverse
Think about it.
double = zipWith ($) (cycle [(*2),id])
EDIT I should note, this isn't really my solution it is the solution of the linked post with the (*2) and id flipped. That's why I said think about it because it was such a trivial fix.
A direct implementation would be:
doubleOddElements :: [Int] -> [Int]
doubleOddElements [] = []
doubleOddElements [x] = [2 * x]
doubleOddElements (x:y:xs) = (2*x):y:(doubleOddElements xs)
Okay, so not elegant or efficient like the other answers, but I wrote this from a beginners standpoint (I am one) in terms of readability and basic functionality.
This doubles every second number, beginning from the right.
Using this script: doubleEveryOther [1,3,6,9,12,15,18] produces [1,6,6,18,12,30,18] and doubleEveryOther [1,3,6,9,12,15] produces [2,3,12,9,24,15]
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther [] = []
doubleEveryOther (x:[]) = [x]
doubleEveryOther (x:y:zs)
| (length (x:y:zs)) `mod` 2 /= 0 = x : y*2 : doubleEveryOther zs
| otherwise = x*2 : y : doubleEveryOther zs
Trying to generalize the problem a bit: Since we want to double every 2nd element from the end, we can't know in advance if it'll be every odd or even from the start. So the easiest way is to construct both, count if the overall size is even or odd, and then decide.
Let's define an Applicative data structure that captures:
Having two variants of values,
keeping the parity of the length (odd/even), and
alternating the two when two such values are combined,
as follows:
import Control.Applicative
import Data.Monoid
import qualified Data.Traversable as T
data Switching m = Switching !Bool m m
deriving (Eq, Ord, Show)
instance Functor Switching where
fmap f (Switching b x y) = Switching b (f x) (f y)
instance Applicative Switching where
pure x = Switching False x x
(Switching False f g) <*> (Switching b2 x y) = Switching b2 (f x) (g y)
(Switching True f g) <*> (Switching b2 x y) = Switching (not b2) (f y) (g x)
So traversing a list will yield two lists looking like this:
x1 y2 x3 y4 ...
y1 x2 y3 x4 ...
two zig-zag-ing copies. Now we can compute
double2 :: (Num m) => m -> Switching m
double2 x = Switching True (2 * x) x
double2ndRight :: (Num m, T.Traversable f) => f m -> f m
double2ndRight k = case T.traverse double2 k of
Switching True _ y -> y
Switching False x _ -> x
Here are mine two solutions, note that I'm complete beginner in Haskell.
First one uses list functions, head, tail and lenght:
doubleSecondFromEnd :: [Integer] -> [Integer]
doubleSecondFromEnd [] = [] -- Do nothing on empty list
doubleSecondFromEnd n
| length n `mod` 2 == 0 = head n * 2 : doubleSecondFromEnd (tail n)
| otherwise = head n : doubleSecondFromEnd (tail n)
Second one, similar but with a different approach only uses length function:
doubleSecondFromEnd2 :: [Integer] -> [Integer]
doubleSecondFromEnd2 [] = [] -- Do nothing on empty list
doubleSecondFromEnd2 (x:y)
| length y `mod` 2 /= 0 = x * 2 : doubleSecondFromEnd2 y
| otherwise = x : doubleSecondFromEnd2 y
I am just learning Haskell so please find the following beginner solution. I try to use limited cool functions like zipWith , cycle, or reverse
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther [] = []
doubleEveryOther s#(x:xs)
| (length s) `mod` 2 == 0 = (x * 2) : (doubleEveryOther xs)
| otherwise = x : (doubleEveryOther xs)
The key thing to note that when doubling every element from the right you can put the doubling into two cases:
If the list is even length, you will ultimately end up doubling the first element of the list.
If the list is odd length, you will not be doubling the first element of the list.
I answered this as part of the homework assignment from CS194
My first thought was:
doubleOdd (x:xs) = (2*x):(doubleEven xs)
doubleOdd [] = []
doubleEven (x:xs) = x:(doubleOdd xs)
doubleEven [] = []
DiegoNolan's solution is more elegant, in that the function and sequence length are more easily altered, but it took me a moment to grok.
Adding the requirement to operate from the right makes it a little more complex. foldr is a neat starting point for doing something from the right, so let me try:
doubleOddFromRight = third . foldr builder (id,double,[])
where third (_,_,x) = x
builder x (fx,fy,xs) = (fy, fx, fx x : xs)
double x = 2 * x
This swaps the two functions fx and fy for each entry. To find the value of any entry will require a traversal to the end of the list, finding whether the length was odd or even.
This is my answer to this CIS 194 homework assignment. It's implemented using just the stuff that was introduced in lecture 1 + reverse.
doubleEveryOtherLeftToRight :: [Integer] -> [Integer]
doubleEveryOtherLeftToRight [] = []
doubleEveryOtherLeftToRight (x:[]) = [x]
doubleEveryOtherLeftToRight (x:y:zs) = x:y*2:(doubleEveryOtherLeftToRight zs)
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther xs = reverse (doubleEveryOtherLeftToRight (reverse xs))
How about this for simplicity?
doubleEveryOtherRev :: [Integer] -> [Integer]
doubleEveryOtherRev l = doubleRev (reverse l) []
where
doubleRev [] a = a
doubleRev (x:[]) a = (x:a)
doubleRev (x:y:zs) a = doubleRev zs (2*y:x:a)
You would have to feed a reversed list of digits, in case you followed that course's recommendation, because it will double every other element as it reverses again. I think that this is different than using twice the reverse function, with another to double every other digit in between, because you won't need to know the full extent of their list by the second time. In other words, it solves that course's problem, but someone correct me if I'm wrong.
We can also do it like this:
doubleEveryOther = reverse . zipWith (*) value . reverse
where
value = 1 : 2 : value
Some answers seems not deal with odd/even length of list.
doubleEveryOtherEvenList = zipWith ($) (cycle [(*2),id])
doubleEveryOther :: [Int] -> [Int]
doubleEveryOther n
| length n `mod` 2 == 0 = doubleEveryOtherEvenList n
| otherwise = (head n) : doubleEveryOtherEvenList (tail n)
Taking an edx course in haskell, this is my noob solution.
doubleSecondR :: [Integer] -> [Integer]
doubleSecondR xs = reverse(zipWith (*) (reverse xs) ys)
where ys = repeat' [1,2]
repeat' :: [a] -> [a]
repeat' xs = xs ++ repeat' xs
I'm too coming to this question from the CIS 194 course.
I did this two ways. First I figured that the point of the question should only rely on functions or ways of programming mentioned in either of the 3 possible sources listed. The course lecture 1, Real World Haskell ch. 1,2 and Learn You a Haskell ch. 2.
So OK:
Recursion, conditionals
reverse, basic functions like max, min, odd, even
list functions e.g. head, tail, ...
Not OK:
foldr, foldl, map
Higher Order functions
Anything beyond these
First solution, just using recursion with a counter:
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther xs = loopDoubles xs 1
loopDoubles :: [Integer] -> Integer -> [Integer]
loopDoubles [] _ = []
loopDoubles xs n = loopDoubles (init xs) (n + 1) ++ [doubleEven (last xs) n]
doubleEven :: Integer -> Integer -> Integer
doubleEven x n = if even n then x * 2 else x
This method uses recursion, but avoids calculating the length at each level of the recursion.
Second method breaking the aforemention rules of mine:
doubleEveryOther' :: [Integer] -> [Integer]
doubleEveryOther' xs = map (\x -> if even (fst x) then (snd x) * 2 else snd x) $ zip (reverse [1..n]) xs
where n = length(xs)
This second one works by building up a reversed set of indexes and then mapping over these. This does calculate the length but only once.
e.g. [1,1,1,1] -> [(4,1),(3,1),(2,1),(1,1)]
Both of these are following the requirement of doubling every other element from the right.
> doubleEveryOther [1,2,3,4]
[2,2,6,4]
> doubleEveryOther [1,2,3]
[1,4,3]
> doubleEveryOther' [1,2,3,4]
[2,2,6,4]
> doubleEveryOther' [1,2,3]
[1,4,3]
I'm guessing the OP posed this question while researching an answer to the Homework 1 assignment from Haskell CIS194 Course. Very little Haskell has been imparted to the student at that stage of the course, so while the above answers are correct, they're beyond the comprehension of the learning student because elements such as lambdas, function composition (.), and even library routines like length and reverse haven't been introduced yet. Here is an answer that matches the stage of teaching in the course:
doubleEveryOtherEven :: [Integer] -> [Integer]
doubleEveryOtherEven [] = []
doubleEveryOtherEven (x:y:xs) = x*2 : y : doubleEveryOtherEven xs
doubleEveryOtherOdd :: [Integer] -> [Integer]
doubleEveryOtherOdd (x:[]) = [x]
doubleEveryOtherOdd (x:y:xs) = x : y*2 : doubleEveryOtherOdd xs
integerListLen :: [Integer] -> Integer
integerListLen [] = 0
integerListLen (x:xs) = 1 + integerListLen xs
doubleEveryOther :: [Integer] -> [Integer]
doubleEveryOther xs
| integerListLen xs `mod` 2 == 0 = doubleEveryOtherEven xs -- also handles empty list case
| otherwise = doubleEveryOtherOdd xs
The calculation requires foreknowledge on whether the list has an even or odd number of elements, to determine which digit in each pair of digits should be doubled. However, basic Haskell pattern-matching only permits matching list elements from left-to-right (example: x:xs), which means you can't determine if there are an odd or even number of elements until you've reached the end of the list, but by then it's too late since you need to do calculations on each left-hand pair of elements while working through the list to reach the end.
The solution is to split the doubling logic into two functions - one which handles even-length lists and another which handles odd-length lists. A third function is needed to determine which of those two functions to call for a given list, which in turn needs an additional function that can calculate the length of the list so we can establish whether the list has an odd or even number of elements (again, since the length library function hasn't been introduced at this stage of the course).
This solution is also in keeping with the advisory in the Week 1 lesson, which states: "It’s good Haskell style to build up more complex functions by combining many simple ones."
Here is my answer for CIS 194 homework1.
I took idea from toDigits and toDigitsRev. It's not fancy, but works.
takeLastTwo :: [Int] -> [Int]
takeLastTwo [] = []
takeLastTwo (x : y : []) = [x, y]
takeLastTwo (x : xs) = takeLastTwo xs
removeLastTwo :: [Int] -> [Int]
removeLastTwo [] = []
removeLastTwo (x : y : []) = []
removeLastTwo (x : xs) = x : removeLastTwo xs
doubleEveryOther :: [Int] -> [Int]
doubleEveryOther [] = []
doubleEveryOther (x : []) = [x]
doubleEveryOther (x : y : []) = (2 * x) : y : []
doubleEveryOther xs = doubleEveryOther (removeLastTwo xs) ++ doubleEveryOther (takeLastTwo xs)

Calculating list cumulative sum in Haskell

Write a function that returns the running sum of list. e.g. running [1,2,3,5] is [1,3,6,11]. I write this function below which just can return the final sum of all the values among the list.So how can i separate them one by one?
sumlist' xx=aux xx 0
where aux [] a=a
aux (x:xs) a=aux xs (a+x)
I think you want a combination of scanl1 and (+), so something like
scanl1 (+) *your list here*
scanl1 will apply the given function across a list, and report each intermediate value into the returned list.
Like, to write it out in pseudo code,
scanl1 (+) [1,2,3]
would output a list like:
[a, b, c] where { a = 1, b = a+2, c = b+3 }
or in other words,
[1, 3, 6]
Learn You A Haskell has a lot of great examples and descriptions of scans, folds, and much more of Haskell's goodies.
Hope this helps.
You can adjust your function to produce a list by simply prepending a+x to the result on each step and using the empty list as the base case:
sumlist' xx = aux xx 0
where aux [] a = []
aux (x:xs) a = (a+x) : aux xs (a+x)
However it is more idiomatic Haskell to express this kind of thing as a fold or scan.
While scanl1 is clearly the "canonical" solution, it is still instructive to see how you could do it with foldl:
sumList xs = tail.reverse $ foldl acc [0] xs where
acc (y:ys) x = (x+y):y:ys
Or pointfree:
sumList = tail.reverse.foldl acc [0] where
acc (y:ys) x = (x+y):y:ys
Here is an ugly brute force approach:
sumList xs = reverse $ acc $ reverse xs where
acc [] = []
acc (x:xs) = (x + sum xs) : acc xs
There is a cute (but not very performant) solution using inits:
sumList xs = tail $ map sum $ inits xs
Again pointfree:
sumList = tail.map sum.inits
Related to another question I found this way:
rsum xs = map (\(a,b)->a+b) (zip (0:(rsum xs)) xs)
I think it is even quite efficient.
I am not sure how canonical is this but it looks beautiful to me :)
sumlist' [] = []
sumlist' (x:xs) = x : [x + y | y <- sumlist' xs]
As others have commented, it would be nice to find a solution that is both linear and non-strict. The problem is that the right folds and scans do not allow you to look at items to the left of you, and the left folds and scans are all strict on the input list. One way to achieve this is to define our own function which folds from the right but looks to the left. For example:
sumList:: Num a => [a] -> [a]
sumList xs = foldlr (\x l r -> (x + l):r) 0 [] xs
It's not too difficult to define foldr so that it is non-strict in the list. Note that it has to have two initialisers -- one going from the left (0) and one terminating from the right ([]):
foldlr :: (a -> b -> [b] -> [b]) -> b -> [b] -> [a] -> [b]
foldlr f l r xs =
let result = foldr (\(l', x) r' -> f x l' r') r (zip (l:result) xs) in
result

Resources