Implementing take using foldr - haskell

This is my take version using foldr:
myTake n list = foldr step [] list
where step x y | (length y) < n = x : y
| otherwise = y
main = do print $ myTake 2 [1,2,3,4]
The output is not what I expect:
[3,4]
I then tried to debug by inserting the length of y into itself and the result was:
[3,2,1,0]
I don't understand why the lengths are inserted in decreasing order. Perhaps something obvious I missed?

If you want to implement take using foldr you need to simulate traversing the list from left to right. The point is to make the folding function depend on an extra argument which encodes the logic you want and not only depend on the folded tail of the list.
take :: Int -> [a] -> [a]
take n xs = foldr step (const []) xs n
where
step x g 0 = []
step x g n = x:g (n-1)
Here, foldr returns a function which takes a numeric argument and traverses the list from left to right taking from it the amount required. This will also work on infinite lists due to laziness. As soon as the extra argument reaches zero, foldr will short-circuit and return an empty list.

foldr will apply the function step starting from the *last elements**. That is,
foldr step [] [1,2,3,4] == 1 `step` (2 `step` (3 `step` (4 `step` [])))
== 1 `step` (2 `step` (3 `step` (4:[])))
== 1 `step` (2 `step (3:4:[])) -- length y == 2 here
== 1 `step` (3:4:[])
== 3:4:[]
== [3, 4]
The lengths are "inserted" in decreasing order because : is a prepending operation. The longer lengths are added to the beginning of the list.
(Image taken from http://en.wikipedia.org/wiki/Fold_%28higher-order_function%29)
*: For simplicity, we assume every operation is strict, which is true in OP's step implementation.

The other answers so far are making it much too complicated, because they seem excessively wedded to the notion that foldr works "from right to left." There is a sense in which it does, but Haskell is a lazy language, so a "right to left" computation that uses a lazy fold step will actually be executed from left to right, as the result is consumed.
Study this code:
take :: Int -> [a] -> [a]
take n xs = foldr step [] (tagFrom 1 xs)
where step (a, i) rest
| i > n = []
| otherwise = a:rest
tagFrom :: Enum i => i -> [a] -> [(a, i)]
tagFrom i xs = zip xs [i..]

Related

How to create a Infinite List in Haskell where the new value consumes all the previous values

If I create a infinite list like this:
let t xs = xs ++ [sum(xs)]
let xs = [1,2] : map (t) xs
take 10 xs
I will get this result:
[
[1,2],
[1,2,3],
[1,2,3,6],
[1,2,3,6,12],
[1,2,3,6,12,24],
[1,2,3,6,12,24,48],
[1,2,3,6,12,24,48,96],
[1,2,3,6,12,24,48,96,192],
[1,2,3,6,12,24,48,96,192,384],
[1,2,3,6,12,24,48,96,192,384,768]
]
This is pretty close to what I am trying to do.
This current code uses the last value to define the next. But, instead of a list of lists, I would like to know some way to make an infinite list that uses all the previous values to define the new one.
So the output would be only
[1,2,3,6,12,24,48,96,192,384,768,1536,...]
I have the definition of the first element [1].
I have the rule of getting a new element, sum all the previous elements.
But, I could not put this in the Haskell grammar to create the infinite list.
Using my current code, I could take the list that I need, using the command:
xs !! 10
> [1,2,3,6,12,24,48,96,192,384,768,1536]
But, it seems to me, that it is possible doing this in some more efficient way.
Some Notes
I understand that, for this particular example, that was intentionally oversimplified, we could create a function that uses only the last value to define the next.
But, I am searching if it is possible to read all the previous values into an infinite list definition.
I am sorry if the example that I used created some confusion.
Here another example, that is not possible to fix using reading only the last value:
isMultipleByList :: Integer -> [Integer] -> Bool
isMultipleByList _ [] = False
isMultipleByList v (x:xs) = if (mod v x == 0)
then True
else (isMultipleByList v xs)
nextNotMultipleLoop :: Integer -> Integer -> [Integer] -> Integer
nextNotMultipleLoop step v xs = if not (isMultipleByList v xs)
then v
else nextNotMultipleLoop step (v + step) xs
nextNotMultiple :: [Integer] -> Integer
nextNotMultiple xs = if xs == [2]
then nextNotMultipleLoop 1 (maximum xs) xs
else nextNotMultipleLoop 2 (maximum xs) xs
addNextNotMultiple xs = xs ++ [nextNotMultiple xs]
infinitePrimeList = [2] : map (addNextNotMultiple) infinitePrimeList
take 10 infinitePrimeList
[
[2,3],
[2,3,5],
[2,3,5,7],
[2,3,5,7,11],
[2,3,5,7,11,13],
[2,3,5,7,11,13,17],
[2,3,5,7,11,13,17,19],
[2,3,5,7,11,13,17,19,23],
[2,3,5,7,11,13,17,19,23,29],
[2,3,5,7,11,13,17,19,23,29,31]
]
infinitePrimeList !! 10
[2,3,5,7,11,13,17,19,23,29,31,37]
You can think so:
You want to create a list (call them a) which starts on [1,2]:
a = [1,2] ++ ???
... and have this property: each next element in a is a sum of all previous elements in a. So you can write
scanl1 (+) a
and get a new list, in which any element with index n is sum of n first elements of list a. So, it is [1, 3, 6 ...]. All you need is take all elements without first:
tail (scanl1 (+) a)
So, you can define a as:
a = [1,2] ++ tail (scanl1 (+) a)
This way of thought you can apply with other similar problems of definition list through its elements.
If we already had the final result, calculating the list of previous elements for a given element would be easy, a simple application of the inits function.
Let's assume we already have the final result xs, and use it to compute xs itself:
import Data.List (inits)
main :: IO ()
main = do
let is = drop 2 $ inits xs
xs = 1 : 2 : map sum is
print $ take 10 xs
This produces the list
[1,2,3,6,12,24,48,96,192,384]
(Note: this is less efficient than SergeyKuz1001's solution, because the sum is re-calculated each time.)
unfoldr has a quite nice flexibility to adapt to various "create-a-list-from-initial-conditions"-problems so I think it is worth mentioning.
A little less elegant for this specific case, but shows how unfoldr can be used.
import Data.List
nextVal as = Just (s,as++[s])
where s = sum as
initList = [1,2]
myList =initList ++ ( unfoldr nextVal initList)
main = putStrLn . show . (take 12) $ myList
Yielding
[1,2,3,6,12,24,48,96,192,384,768,1536]
in the end.
As pointed out in the comment, one should think a little when using unfoldr. The way I've written it above, the code mimicks the code in the original question. However, this means that the accumulator is updated with as++[s], thus constructing a new list at every iteration. A quick run at https://repl.it/languages/haskell suggests it becomes quite memory intensive and slow. (4.5 seconds to access the 2000nd element in myList
Simply swapping the acumulator update to a:as produced a 7-fold speed increase. Since the same list can be reused as accumulator in every step it goes faster. However, the accumulator list is now in reverse, so one needs to think a little bit. In the case of predicate function sum this makes no differece, but if the order of the list matters, one must think a little bit extra.
You could define it like this:
xs = 1:2:iterate (*2) 3
For example:
Prelude> take 12 xs
[1,2,3,6,12,24,48,96,192,384,768,1536]
So here's my take. I tried not to create O(n) extra lists.
explode ∷ Integral i ⇒ (i ->[a] -> a) -> [a] -> [a]
explode fn init = as where
as = init ++ [fn i as | i <- [l, l+1..]]
l = genericLength init
This convenience function does create additional lists (by take). Hopefully they can be optimised away by the compiler.
explode' f = explode (\x as -> f $ take x as)
Usage examples:
myList = explode' sum [1,2]
sum' 0 xs = 0
sum' n (x:xs) = x + sum' (n-1) xs
myList2 = explode sum' [1,2]
In my tests there's little performance difference between the two functions. explode' is often slightly better.
The solution from #LudvigH is very nice and clear. But, it was not faster.
I am still working on the benchmark to compare the other options.
For now, this is the best solution that I could find:
-------------------------------------------------------------------------------------
-- # infinite sum of the previous using fuse
-------------------------------------------------------------------------------------
recursiveSum xs = [nextValue] ++ (recursiveSum (nextList)) where
nextValue = sum(xs)
nextList = xs ++ [nextValue]
initialSumValues = [1]
infiniteSumFuse = initialSumValues ++ recursiveSum initialSumValues
-------------------------------------------------------------------------------------
-- # infinite prime list using fuse
-------------------------------------------------------------------------------------
-- calculate the current value based in the current list
-- call the same function with the new combined value
recursivePrimeList xs = [nextValue] ++ (recursivePrimeList (nextList)) where
nextValue = nextNonMultiple(xs)
nextList = xs ++ [nextValue]
initialPrimes = [2]
infiniteFusePrimeList = initialPrimes ++ recursivePrimeList initialPrimes
This approach is fast and makes good use of many cores.
Maybe there is some faster solution, but I decided to post this to share my current progress on this subject so far.
In general, define
xs = x1 : zipWith f xs (inits xs)
Then it's xs == x1 : f x1 [] : f x2 [x1] : f x3 [x1, x2] : ...., and so on.
Here's one example of using inits in the context of computing the infinite list of primes, which pairs them up as
ps = 2 : f p1 [p1] : f p2 [p1,p2] : f p3 [p1,p2,p3] : ...
(in the definition of primes5 there).

Haskell naive duplicate filtering

I do not understand a sample solution for the following problem: given a list of elements, remove the duplicates. Then count the unique digits of a number. No explicit recursion may be used for either problem.
My code:
removeDuplicates :: Eq a => [a] -> [a]
removeDuplicates = foldr (\x ys -> x:(filter (x /=) ys)) []
differentDigits :: Int -> Int
differentDigits xs = length (removeDuplicates (show xs))
The solution I am trying to understand has a different definition for differentDigits, namely
differentDigits xs = foldr (\ _ x -> x + 1) 0 ( removeDuplicates ( filter (/= '_') ( show xs )))
Both approaches work, but I cannot grasp the sample solution. To break my question down into subquestions,
How does the first argument to filter work? I mean
(/= '_')
How does the lambda for foldr work? In
foldr (\ _ x -> x + 1)
^
the variable x should still be the Char list? How does Haskell figure out that actually 0 should be incremented?
filter (/= '_') is, I'm pretty sure, redundant. It filters out underscore characters, which shouldn't be present in the result of show xs, assuming xs is a number of some sort.
foldr (\ _ x -> x + 1) 0 is equivalent to length. The way foldr works, it takes the second argument (which in your example is zero) as the starting point, then applies the first argument (in your example, lambda) to it over and over for every element of the input list. The element of the input list is passed into the lambda as first argument (denoted _ in your example), and the running sum is passed as second argument (denoted x). Since the lambda just returns a "plus one" number on every pass, the result will be a number representing how many times the lambda was called - which is the length of the list.
First, note that (2) is written in so called point free style, leaving out the third argument of foldr.
https://en.wikipedia.org/wiki/Tacit_programming#Functional_programming
Also, the underscore in \_ x -> x + 1 is a wild card, that simply marks the place of a parameter but that does not give it a name (a wild card works as a nameless parameter).
Second, (2) is a really nothing else than a simple recursive function that folds to the right. foldr is a compact way to write such recursive functions (in your case length):
foldr :: (a -> b -> b) -> b -> [a]
foldr f z [] = z
foldr f z (x:xs) = f x (foldr f z xs)
If we write
foldr f c ls
ls is the list over which our recursive function should recur (a is the type of the elements).
c is the result in the base case (when the recursive recursive function is applied on an empty list).
f computes the result in the general case (when the recursive function is applied on a non-empty list). f takes two arguments:
The head of the list and
the result of the recursive call on the tail of the list.
So, given f and c, foldr will go through the list ls recursively.
A first example
The Wikipedia page about point free style gives the example of how we can compute the sum of all elements in a list using foldr:
Instead of writing
sum [] = 0
sum (x:xs) = x + sum xs
we can write
sum = foldr (+) 0
The operator section (+) is a 2-argument function that adds its arguments. The expression
sum [1,2,3,4]
is computed as
1 + (2 + (3 + (4)))
(hence "folding to the right").
Example: Multiplying all elements.
Instead of
prod [] = 1
prod (x:xs) = x * prod xs
we can write
prod = foldr (*) 1
Example: Remove all occurrences of a value from a list.
Instead of
remove _ [] = []
remove v (x:xs) = if x==v then remove v xs else x:remove v xs
we can write
remove v = foldr (\x r -> if x==v then r else x:r) []
Your case, (2)
We can now fully understand that
length = foldr (\ _ x -> x + 1) 0
in fact is the same as
length [] = 0
length (x:xs) = length xs + 1
that is, the length function.
Hope this recursive view on foldr helped you understand the code.

Define function in Haskell using foldr

I'm trying to define a function in Haskell using the foldr function:
fromDigits :: [Int] -> Int
This function takes a list of Ints (each on ranging from 0 to 9) and converts to a single Int. For example:
fromDigits [0,1] = 10
fromDigits [4,3,2,1] = 1234
fromDigits [2,3,9] = 932
fromDigits [2,3,9,0,1] = 10932
Anyway, I have no trouble defining this using explicit recursion or even using zipWith:
fromDigits n = sum (zipWith (*) n (map ((^)10) [0..]))
But now I have to define it using a foldr, but I don't know how to get the powers of 10. What I have is:
fromDigits xs = foldr (\x acc -> (x*10^(???)) + acc) 0 xs
How can I get them to decrease? I know I can start with (length xs - 1) but what then?
Best Regards
You were almost there:
your
fromDigits xs = foldr (\x acc -> (x*10^(???)) + acc) 0 xs
is the solution with 2 little changes:
fromDigits = foldr (\x acc -> acc*10 + x) 0
(BTW I left out the xs on each sides, that's not necessary.
Another option would be
fromDigits = foldl (\x acc -> read $ (show x) ++ (show acc)) 0
The nice thing about foldr is that it's so extemely easy to visualise!
foldr f init [a,b, ... z]
≡ foldr f init $ a : b : ... z : []
≡ a`f b`f`... z`f`init
≡ f a (f b ( ... (f z init)...)))
so as you see, the j-th list element is used in j consecutive calls of f. The head element is merely passed once to the left of the function. For you application, the head element is the last digit. How should that influence the outcome? Well, it's just added to the result, isn't it?
15 = 10 + 5
623987236705839 = 623987236705830 + 9
– obvious. Then the question is, how do you take care for the other digits? Well, to employ the above trick you first need to make sure there's a 0 in the last place of the carried subresult. A 0 that does not come from the supplied digits! How do you add such a zero?
That should really be enough hint given now.
The trick is, you don't need to compute the power of 10 each time from scratch, you just need to compute it based on the previous power of ten (i.e. multiply by 10). Well, assuming you can reverse the input list.
(But the lists you give above are already in reverse order, so arguably you should be able to re-reverse them and just say that your function takes a list of digits in the correct order. If not, then just divide by 10 instead of multiplying by 10.)

Split list and make sum from sublist?

im searching for a solution for my Haskell class.
I have a list of numbers and i need to return SUM for every part of list. Parts are divided by 0. I need to use FOLDL function.
Example:
initial list: [1,2,3,0,3,4,0,5,2,1]
sublist [[1,2,3],[3,4],[5,2,1]]
result [6,7,7]
I have a function for finding 0 in initial list:
findPos list = [index+1 | (index, e) <- zip [0..] list, e == 0]
(returns [4,6] for initial list from example)
and function for making SUM with FOLDL:
sumList list = foldl (+) 0 list
But I completely failed to put it together :/
---- MY SOLUTION
In the end I found something completely different that you guys suggested.
Took me whole day to make it :/
groups :: [Int] -> [Int]
groups list = [sum x | x <- makelist list]
makelist :: [Int] -> [[Int]]
makelist xs = reverse (foldl (\acc x -> zero x acc) [[]] xs)
zero :: Int -> [[Int]] -> [[Int]]
zero x acc | x == 0 = addnewtolist acc
| otherwise = addtolist x acc
addtolist :: Int -> [[Int]] -> [[Int]]
addtolist i listlist = (i : (head listlist)) : (drop 1 listlist)
addnewtolist :: [[Int]] -> [[Int]]
addnewtolist listlist = [] : listlist
I'm going to give you some hints, rather than a complete solution, since this sounds like it may be a homework assignment.
I like the breakdown of steps you've suggested. For the first step (going from a list of numbers with zero markers to a list of lists), I suggest doing an explicit recursion; try this for a template:
splits [] = {- ... -}
splits (0:xs) = {- ... -}
splits (x:xs) = {- ... -}
You can also abuse groupBy if you're careful.
For the second step, it looks like you're almost there; the last step you need is to take a look at the map :: (a -> b) -> ([a] -> [b]) function, which takes a normal function and runs it on each element of a list.
As a bonus exercise, you might want to think about how you might do the whole thing in one shot as a single fold. It's possible -- and even not too difficult, if you track through what the types of the various arguments to foldr/foldl would have to be!
Additions since the question changed:
Since it looks like you've worked out a solution, I now feel comfortable giving some spoilers. =)
I suggested two possible implementations; one that goes step-by-step, as you suggested, and another that goes all at once. The step-by-step one could look like this:
splits [] = []
splits (0:xs) = [] : splits xs
splits (x:xs) = case splits xs of
[] -> [[x]]
(ys:yss) -> ((x:ys):yss)
groups' = map sum . splits
Or like this:
splits' = groupBy (\x y -> y /= 0)
groups'' = map sum . splits'
The all-at-once version might look like this:
accumulate 0 xs = 0:xs
accumulate n (x:xs) = (n+x):xs
groups''' = foldr accumulate [0]
To check that you understand these, here are a few exercises you might like to try:
What do splits and splits' do with [1,2,3,0,4,5]? [1,2,0,3,4,0]? [0]? []? Check your predictions in ghci.
Predict what each of the four versions of groups (including yours) output for inputs like [] or [1,2,0,3,4,0], and then test your prediction in ghci.
Modify groups''' to exhibit the behavior of one of the other implementations.
Modify groups''' to use foldl instead of foldr.
Now that you've completed the problem on your own, I am showing you a slightly less verbose version. Foldr seems better in my opinion to this problem*, but because you asked for foldl I will show you my solution using both functions.
Also, your example appears to be incorrect, the sum of [5,2,1] is 8, not 7.
The foldr version.
makelist' l = foldr (\x (n:ns) -> if x == 0 then 0:(n:ns) else (x + n):ns) [0] l
In this version, we traverse the list, if the current element (x) is a 0, we add a new element to the accumulator list (n:ns). Otherwise, we add the value of the current element to the value of the front element of the accumulator, and replace the front value of the accumulator with this value.
Step by step:
acc = [0], x = 1. Result is [0+1]
acc = [1], x = 2. Result is [1+2]
acc = [3], x = 5. Result is [3+5]
acc = [8], x = 0. Result is 0:[8]
acc = [0,8], x = 4. Result is [0+4,8]
acc = [4,8], x = 3. Result is [4+3,8]
acc = [7,8], x = 0. Result is 0:[7,8]
acc = [0,7,8], x = 3. Result is [0+3,7,8]
acc = [3,7,8], x = 2. Result is [3+2,7,8]
acc = [5,7,8], x = 1. Result is [5+1,7,8] = [6,7,8]
There you have it!
And the foldl version. Works similarly as above, but produces a reversed list, hence the use of reverse at the beginning of this function to unreverse the list.
makelist l = reverse $ foldl (\(n:ns) x -> if x == 0 then 0:(n:ns) else (x + n):ns) [0] l
*Folding the list from the right allows the cons (:) function to be used naturally, using my method with a left fold produces a reversed list. (There is likely a simpler way to do the left fold version that I did not think of that eliminates this triviality.)
As you already solved it, another version:
subListSums list = reverse $ foldl subSum [0] list where
subSum xs 0 = 0 : xs
subSum (x:xs) n = (x+n) : xs
(Assuming that you have only non-negative numbers in the list)

How to define a rotates function

How to define a rotates function that generates all rotations of the given list?
For example: rotates [1,2,3,4] =[[1,2,3,4],[2,3,4,1],[3,4,1,2],[4,1,2,3]]
I wrote a shift function that can rearrange the order
shift ::[Int]->[Int]
shift x=tail ++ take 1 x
but I don't how to generate these new arrays and append them together.
Another way to calculate all rotations of a list is to use the predefined functions tails and inits. The function tails yields a list of all final segments of a list while inits yields a list of all initial segments. For example,
tails [1,2,3] = [[1,2,3], [2,3], [3], []]
inits [1,2,3] = [[], [1], [1,2], [1,2,3]]
That is, if we concatenate these lists pointwise as indicated by the indentation we get all rotations. We only get the original list twice, namely, once by appending the empty initial segment at the end of original list and once by appending the empty final segment to the front of the original list. Therefore, we use the function init to drop the last element of the result of applying zipWith to the tails and inits of a list. The function zipWith applies its first argument pointwise to the provided lists.
allRotations :: [a] -> [[a]]
allRotations l = init (zipWith (++) (tails l) (inits l))
This solution has an advantage over the other solutions as it does not use length. The function length is quite strict in the sense that it does not yield a result before it has evaluated the list structure of its argument completely. For example, if we evaluate the application
allRotations [1..]
that is, we calculate all rotations of the infinite list of natural numbers, ghci happily starts printing the infinite list as first result. In contrast, an implementation that is based on length like suggested here does not terminate as it calculates the length of the infinite list.
shift (x:xs) = xs ++ [x]
rotates xs = take (length xs) $ iterate shift xs
iterate f x returns the stream ("infinite list") [x, f x, f (f x), ...]. There are n rotations of an n-element list, so we take the first n of them.
The following
shift :: [a] -> Int -> [a]
shift l n = drop n l ++ take n l
allRotations :: [a] -> [[a]]
allRotations l = [ shift l i | i <- [0 .. (length l) -1]]
yields
> ghci
Prelude> :l test.hs
[1 of 1] Compiling Main ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main> allRotations [1,2,3,4]
[[1,2,3,4],[2,3,4,1],[3,4,1,2],[4,1,2,3]]
which is as you expect.
I think this is fairly readable, although not particularly efficient (no memoisation of previous shifts occurs).
If you care about efficiency, then
shift :: [a] -> [a]
shift [] = []
shift (x:xs) = xs ++ [x]
allRotations :: [a] -> [[a]]
allRotations l = take (length l) (iterate shift l)
will allow you to reuse the results of previous shifts, and avoid recomputing them.
Note that iterate returns an infinite list, and due to lazy evaluation, we only ever evaluate it up to length l into the list.
Note that in the first part, I've extended your shift function to ask how much to shift, and I've then a list comprehension for allRotations.
The answers given so far work fine for finite lists, but will eventually error out when given an infinite list. (They all call length on the list.)
shift :: [a] -> [a]
shift xs = drop 1 xs ++ take 1 xs
rotations :: [a] -> [[a]]
rotations xs = zipWith const (iterate shift xs) xs
My solution uses zipWith const instead. zipWith const foos bars might appear at first glance to be identical to foos (recall that const x y = x). But the list returned from zipWith terminates when either of the input lists terminates.
So when xs is finite, the returned list is the same length as xs, as we want; and when xs is infinite, the returned list will not be truncated, so will be infinite, again as we want.
(In your particular application it may not make sense to try to rotate an infinite list. On the other hand, it might. I submit this answer for completeness only.)
I would prefer the following solutions, using the built-in functions cycle and tails:
rotations xs = take len $ map (take len) $ tails $ cycle xs where
len = length xs
For your example [1,2,3,4] the function cycle produces an infinite list [1,2,3,4,1,2,3,4,1,2...]. The function tails generates all possible tails from a given list, here [[1,2,3,4,1,2...],[2,3,4,1,2,3...],[3,4,1,2,3,4...],...]. Now all we need to do is cutting down the "tails"-lists to length 4, and cutting the overall list to length 4, which is done using take. The alias len was introduced to avoid to recalculate length xs several times.
I think it will be something like this (I don't have ghc right now, so I couldn't try it)
shift (x:xs) = xs ++ [x]
rotateHelper xs 0 = []
rotateHelper xs n = xs : (rotateHelper (shift xs) (n - 1))
rotate xs = rotateHelper xs (length xs)
myRotate lst = lst : myRotateiter lst lst
where myRotateiter (x:xs) orig
|temp == orig = []
|otherwise = temp : myRotateiter temp orig
where temp = xs ++ [x]
I suggest:
rotate l = l : rotate (drop 1 l ++ take 1 l)
distinctRotations l = take (length l) (rotate l)

Resources