Haskell takeWhile + 1 - haskell

How can I write a takeWhile that would keep the first element that doesn't match the condition?
Example (obviously my example is trickier than this) :
Instead of takeWhile (\× - > x! = 3) [1..10] to return [1,2] I need [1,2,3].
I thought of (takeWhile myFunc myList) ++ [find myFunc myList] but it means I need to go through my list 2 times...
Any idea?

You can use span or break.
λ> span (/=3) [1..10]
([1,2],[3,4,5,6,7,8,9,10])
So you can do something like this:
takeWhileInc :: (a -> Bool) -> [a] -> [a]
takeWhileInc p xs = case zs of [] -> error "not found"
(z:_) -> ys ++ [z]
where
(ys, zs) = span p xs
(Or whatever you want to happen when zs is empty because no 3
was found.)

You can roll your own.
takeWhileOneMore :: (a -> Bool) -> [a] -> [a]
takeWhileOneMore p = foldr (\x ys -> if p x then x:ys else [x]) []
Compare it with
takeWhile :: (a -> Bool) -> [a] -> [a]
takeWhile p = foldr (\x ys -> if p x then x:ys else []) []
Explicit recursion would also be fine for this.
takeWhileOneMore :: (a -> Bool) -> [a] -> [a]
takeWhileOneMore p [] = []
takeWhileOneMore p (x:xs) =
if p x
then x : takeWhileOneMore p xs
else [x]

I like to use the base function more than many people do, such as re-using takeWhile in an intelligent way to get the desired result. For example, you can create a new list of predicates with the first element being True and takeWhile this list is true:
takeWhileP1 p xs = map snd (takeWhile fst (zip (True:map p xs) xs)
This generalizes nicely as well (not necessarily efficient in this form):
takeWhilePlusN n p xs = map snd (takeWhile fst (zip (replicate n True ++ map p xs) xs))
Or perhaps easier to read:
takeWhilePlusN n p xs =
let preds = replicate n True ++ map p xs
annotated = zip preds xs
in map snd (takeWhile fst annotated)
And the result:
*Main> takeWhilePlusN 3 (<5) [1..10]
[1,2,3,4,5,6,7]
*Main> takeWhilePlusN 1 (<5) [1..10]
[1,2,3,4,5]
*Main> takeWhileP1 (<5) [1..10]
[1,2,3,4,5]
*Main> takeWhile (<5) [1..10]
[1,2,3,4]

When the condition fails for a element, instead of terminating with empty list, we can return the element.
takeWhileInclusive :: (a->Bool) -> [a] -> [a]
takeWhileInclusive _ [] = []
takeWhileInclusive predicate (x:xs) = if predicate x
then do (x: takeWhileInclusive predicate xs)
else [x]

Related

create a function ved that will only remove the last occurrence of the largest item in the list using recursion

You must use recursion to define rmax2 and you must do so from “scratch”. That is, other than the cons operator, head, tail, and comparisons, you should not use any functions from the Haskell library.
I created a function that removes all instances of the largest item, using list comprehension. How do I remove the last instance of the largest number using recursion?
ved :: Ord a => [a] -> [a]
ved [] =[]
ved as = [ a | a <- as, m /= a ]
where m= maximum as
An easy way to split the problem into two easier subproblems consists in:
get the position index of the rightmost maximum value
write a general purpose function del that eliminates the element of a list at a given position. This does not require an Ord constraint.
If we were permitted to use regular library functions, ved could be written like this:
ved0 :: Ord a => [a] -> [a]
ved0 [] = []
ved0 (x:xs) =
let
(maxVal,maxPos) = maximum (zip (x:xs) [0..])
del k ys = let (ys0,ys1) = splitAt k ys in (ys0 ++ tail ys1)
in
del maxPos (x:xs)
where the pairs produced by zip are lexicographically ordered, thus ensuring the rightmost maximum gets picked.
We need to replace the library functions by manual recursion.
Regarding step 1, that is finding the position of the rightmost maximum, as is commonly done, we can use a recursive stepping function and a wrapper above it.
The recursive step function takes as arguments the whole context of the computation, that is:
current candidate for maximum value, mxv
current rightmost position of maximum value, mxp
current depth into the original list, d
rest of original list, xs
and it returns a pair: (currentMaxValue, currentMaxPos)
-- recursive stepping function:
findMax :: Ord a => a -> Int -> Int -> [a] -> (a, Int)
findMax mxv mxp d [] = (mxv,mxp)
findMax mxv mxp d (x:xs) = if (x >= mxv) then (findMax x d (d+1) xs)
else (findMax mxv mxp (d+1) xs)
-- top wrapper:
lastMaxPos :: Ord a => [a] -> Int
lastMaxPos [] = (-1)
lastMaxPos (x:xs) = snd (findMax x 0 1 xs)
Step 2, eliminating the list element at position k, can be handled in very similar fashion:
-- recursive stepping function:
del1 :: Int -> Int -> [a] -> [a]
del1 k d [] = []
del1 k d (x:xs) = if (d==k) then xs else x : del1 k (d+1) xs
-- top wrapper:
del :: Int -> [a] -> [a]
del k xs = del1 k 0 xs
Putting it all together:
We are now able to write our final recursion-based version of ved. For simplicity, we inline the content of wrapper functions instead of calling them.
-- ensure we're only using authorized functionality:
{-# LANGUAGE NoImplicitPrelude #-}
import Prelude (Ord, Eq, (==), (>=), (+), ($), head, tail,
IO, putStrLn, show, (++)) -- for testing only
ved :: Ord a => [a] -> [a]
ved [] = []
ved (x:xs) =
let
findMax mxv mxp d [] = (mxv,mxp)
findMax mxv mxp d (y:ys) = if (y >= mxv) then (findMax y d (d+1) ys)
else (findMax mxv mxp (d+1) ys)
(maxVal,maxPos) = findMax x 0 1 xs
del1 k d (y:ys) = if (d==k) then ys else y : del1 k (d+1) ys
del1 k d [] = []
in
del1 maxPos 0 (x:xs)
main :: IO ()
main = do
let xs = [1,2,3,7,3,2,1,7,3,5,7,5,4,3]
res = ved xs
putStrLn $ "input=" ++ (show xs) ++ "\n" ++ " res=" ++ (show res)
If you are strictly required to use recursion, you can use 2 helper functions: One to reverse the list and the second to remove the first largest while reversing the reversed list.
This result in a list where the last occurrence of the largest element is removed.
We also use a boolean flag to make sure we don't remove more than one element.
This is ugly code and I really don't like it. A way to make things cleaner would be to move the reversal of the list to a helper function outside of the current function so that there is only one helper function to the main function. Another way is to use the built-in reverse function and use recursion only for the removal.
removeLastLargest :: Ord a => [a] -> [a]
removeLastLargest xs = go (maximum xs) [] xs where
go n xs [] = go' n True [] xs
go n xs (y:ys) = go n (y:xs) ys
go' n f xs [] = xs
go' n f xs (y:ys)
| f && y == n = go' n False xs ys
| otherwise = go' n f (y:xs) ys
Borrowing the implementation of dropWhileEnd from Hackage, we can implement a helper function splitWhileEnd:
splitWhileEnd :: (a -> Bool) -> [a] -> ([a], [a])
splitWhileEnd p = foldr (\x (xs, ys) -> if p x && null xs then ([], x:ys) else (x:xs, ys)) ([],[])
splitWhileEnd splits a list according to a predictor from the end. For example:
ghci> xs = [1,2,3,4,3,2,4,3,2]
ghci> splitWhileEnd (< maximum xs) xs
([1,2,3,4,3,2,4],[3,2])
With this helper function, you can write ven as:
ven :: Ord a => [a] -> [a]
ven xs =
let (x, y) = splitWhileEnd (< maximum xs) xs
in init x ++ y
ghci> ven xs
[1,2,3,4,3,2,3,2]
For your case, you can refactor splitWhileEnd as:
fun p = \x (xs, ys) -> if p x && null xs then ([], x:ys) else (x:xs, ys)
splitWhileEnd' p [] = ([], [])
splitWhileEnd' p (x : xs) = fun p x (splitWhileEnd' p xs)
ven' xs = let (x, y) = splitWhileEnd' (< maximum xs) xs in init x ++ y
If init and ++ are not allowed, you can implement them manually. It's easy!
BTW, I guess this may be your homework for Haskell course. I think it's ridiculous if your teacher gives the limitations. Who is programming from scratch nowadays?
Anyway, you can always work around this kind of limitations by reimplementing the built-in function manually. Good luck!

Haskell - Non-exhaustive pattern for a reason I don't understand

So I'm trying to write a function that, given two lists of integers, adds the ith even number of each list and returns them in another list. In case one of the list doesn't have an ith even number, a 0 is considered. For example, if the lists are [1,2,1,4,6] and [2,2], it returns [4,6,6] ([2+2,4+2,6+0]). I have the following code:
addEven :: [Int] -> [Int] -> [Int]
addEeven [] [] = []
addEeven (x:xs) [] = filter (\g -> g `mod`2 == 0) (x:xs)
addEven [] (y:ys) = filter (\g -> g `mod` 2 == 0) (y:ys)
addEven (x:xs) (y:ys) = (a + b):(addEven as bs)
where
(a:as) = filter (\g -> g `mod` 2 == 0) (x:xs)
(b:bs) = filter (\g -> g `mod` 2 == 0) (y:ys)
When I run that with the previous example, I get:
[4,6*** Exception: ex.hs:(4,1)-(8,101): Non-exhaustive patterns in function addEven
I really can't see what I'm missing, since it doesn't work with any input I throw at it.
A filter might eliminate elements, hence filter (\g -> gmod2 == 0) is not said to return any elements, and thus the patterns (a:as) and (b:bs) might fail.
That being said, I think you make the problem too complex here. You can first define a helper function that adds two elements of a list:
addList :: Num a => [a] -> [a] -> [a]
addList (x:xs) (y:ys) = (x+y) : addList xs ys
addList xs [] = xs
addList [] ys = ys
Then we do the filter on the two parameters, and make a function addEven that looks like:
addEven :: Integral a => [a] -> [a] -> [a]
addEven xs ys = addList (filter even xs) (filter even ys)
or with on :: (b -> b -> c) -> (a -> b) -> a -> a -> c:
import Data.Function(on)
addEven :: Integral a => [a] -> [a] -> [a]
addEven = addList `on` filter even
While using filter is very instinctive in this case, perhaps using filter twice and then summing up the results might be slightly ineffficient for large lists. Why don't we do the job all at once for a change..?
addMatches :: [Int] -> [Int] -> [Int]
addMatches [] [] = []
addMatches [] ys = filter even ys
addMatches xs [] = filter even xs
addMatches xs ys = first [] xs ys
where
first :: [Int] -> [Int] -> [Int] -> [Int]
first rs [] ys = rs ++ filter even ys
first rs (x:xs) ys = rs ++ if even x then second [x] xs ys
else first [] xs ys
second :: [Int] -> [Int] -> [Int] -> [Int]
second [r] xs [] = [r] ++ filter even xs
second [r] xs (y:ys) = if even y then first [r+y] xs ys
else second [r] xs ys
λ> addMatches [1,2,1,4,6] [2,2]
[4,6,6]

In filterM, why is `return (if b then x:ys else ys)` evaluated once after all the lists are created?

filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
filterM p [] = return []
filterM p (x:xs) = do b <- p x
ys <- filterM p xs
return (if b then x:ys else ys)
and
> filterM (\x -> [True,False]) [1,2,3]
[[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]]
Is return (if b then x:ys else ys) evaluated each time a list is created? Is yes, why isn't the result [[1,2,3]],[[1,2]],[[1,3]],[[1]],[[2,3]],[[2]],[[3]],[[]]?
Does the result [[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]] imply that return (if b then x:ys else ys) is evaluated once after all the lists are created?
In short: because the bind function (>>=) for the instance Monad [] is implement with concatMap, not map.
We can desugar the do block as:
filterM :: Monad m => (a -> m Bool) -> [a] -> m [a]
filterM p [] = return []
filterM p (x:xs) = p x >>= \b -> (filterM p xs >>= \ys -> return (if b then x:ys else ys))
For m ~ [], the >>= function is equivalent to flip concatMap, and return x is equivalent to [x], so that means that we can transform this, for a list, into:
filterM :: (a -> [Bool]) -> [a] -> [[a]]
filterM p [] = [[]]
filterM p (x:xs) = concatMap (\b -> concatMap (\ys -> [if b then (x:ys) else ys]) (filterM p xs)) (p x)
A concatMap (\x -> [f x]) is equivalent to map f, since the concatenation of all these singleton lists will result in a list that contains the outcomes of f for all elements in the given list.
It thus means that the above function is equivalent to:
filterM :: (a -> [Bool]) -> [a] -> [[a]]
filterM p [] = [[]]
filterM p (x:xs) = concatMap (\b -> map (\ys -> if b then (x:ys) else ys) (filterM p xs)) (p x)
If p is \_ -> [True, False], it thus means we can replace (p x) with [True, False], and thus obtain:
concatMap (\b -> map (\ys -> if b then (x:ys) else ys) (filterM p xs)) [True, False]
This thus means that concatMap is the concatenation of two lists: one where b is True, and one where b is False, like:
map (\ys -> (x:ys)) (filterM p xs) ++ map (\ys -> ys) (filterM p xs)
The first map will thus prepend all the lists from filterM p xs with x whereas the second one will not. The above expression is thus equivalent to:
map (x:) (filterM p xs) ++ filterM p xs
if filterM p xs contains the powerset of xs, then the above expression will thus contain the powerset of (x:xs).

Reverse a list in haskell 3

example
Input: [1..10]
Output: [1,10,2,9,3,8,4,7,5,6,6,5,7,4,8,3,9,2,10,1]
I tried this
fon(x:y:xs) =reverse (x:xs)
fun (x:y:xs) = x : (fon xs)
what about this:
interweave :: [a] -> [a]
interweave zs = f zs (reverse zs)
where f xs ys = concat $ zipWith (\ x y -> [x,y]) xs ys
example
λ> interweave [1..10]
[1,10,2,9,3,8,4,7,5,6,6,5,7,4,8,3,9,2,10,1]
Since this looks like homework, I'll provide a hint.
You need both the original list and the reversed list. Try something like
foo :: [a] -> [a]
foo xs = bar xs (reverse xs)
bar :: [a] -> [a] -> [a]
...

How would you define map and filter using foldr in Haskell?

I'm doing a bit of self study on functional languages (currently using Haskell). I came across a Haskell based assignment which requires defining map and filter in terms of foldr. For the life of me I'm not fully understanding how to go about this.
For example when I define a map function like:
map' :: (a -> b) -> [a] -> [b]
map' f [] = []
map' f (x:xs) = foldr (\x xs -> (f x):xs) [] xs
I don't know why the first element of the list is always ignored. Meaning that:
map' (*2) [1,2,3,4]
results in [4,6,8] instead of [2,4,6,8]
Similarly, my filter' function:
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p (x:xs) = foldr (\x xs -> if p x then x:xs else xs ) [] xs
when run as:
filter' even [2,3,4,5,6]
results in [4,6] instead of [2,4,6]
Why would this be the case? And how SHOULD I have defined these functions to get the expected results? I'm assuming something is wrong with my lambda expressions...
I wish I could just comment, but alas, I don't have enough karma.
The other answers are all good ones, but I think the biggest confusion seems to be stemming from your use of x and xs.
If you rewrote it as
map' :: (a -> b) -> [a] -> [b]
map' f [] = []
map' f (x:xs) = foldr (\y ys -> (f y):ys) [] xs
you would clearly see that x is not even mentioned on the right-hand side, so there's no way that it could be in the solution.
Cheers
For your first question, foldr already has a case for the empty list, so you need not and should not provide a case for it in your own map.
map' f = foldr (\x xs -> f x : xs) []
The same holds for filter'
filter' p = foldr (\x xs -> if p x then x : xs else xs) []
Nothing is wrong with your lambda expressions, but there is something wrong with your definitions of filter' and map'. In the cons case (x:xs) you eat the head (x) away and then pass the tail to foldr. The foldr function can never see the first element you already ate. :)
Alse note that:
filter' p = foldr (\x xs -> if p x then x : xs else xs) []
is equivalent (η-equivalent) to:
filter' p xs = foldr (\x xs -> if p x then x : xs else xs) [] xs
I would define map using foldr and function composition as follows:
map :: (a -> b) -> [a] -> [b]
map f = foldr ((:).f) []
And for the case of filter:
filter :: (a -> Bool) -> [a] -> [a]
filter p = foldr (\x xs -> if p x then x:xs else xs) []
Note that it is not necessary to pass the list itself when defining functions over lists using foldr or foldl.
The problem with your solution is that you drop the head of the list and then apply the map over the list and
this is why the head of the list is missing when the result is shown.
In your definitions, you are doing pattern matching for x:xs, which means, when your argument is [1,2,3,4], x is bound to 1 and xs is bound to the rest of the list: [2,3,4].
What you should not do is simply throw away x: part. Then your foldr will be working on whole list.
So your definitions should look as follows:
map' :: (a -> b) -> [a] -> [b]
map' f [] = []
map' f xs = foldr (\x xs -> (f x):xs) [] xs
and
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p xs = foldr (\x xs -> if p x then x:xs else xs ) [] xs
I am new to Haskell (in fact I've found this page asking the same question) but this is my understanding of lists and foldr so far:
lists are elements that are linked to the next element with the cons (:) operator. they terminate with the empty list []. (think of it as a binary operator just like addition (+) 1+2+3+4 = 10, 1:2:3:4:[] = [1,2,3,4]
foldr function takes a function that takes two parameters. this will replace the cons operator, which will define how each item is linked to the next.
it also takes the terminal value for the operation, which can be tought as the initial value that will be assigned to the empty list. for cons it is empty list []. if you link an empty list to any list the result is the list itself. so for a sumfunction it is 0. for a multiply function it is 1, etc.
and it takes the list itself
So my solution is as follows:
filter' p = foldr (\x n -> if p x then x : n else n) []
the lambda expression is our link function, which will be used instead of the cons (:) operator. Empty list is our default value for an empty list. If predicate is satisfied we link to the next item using (:) as normal, else we simply don't link at all.
map' f = foldr (\x n -> f x : n) []
here we link f x to the next item instead of just x, which would simply duplicate the list.
Also, note that you don't need to use pattern matching, since we already tell foldr what to do in case of an empty list.
I know this question is really old but I just wanted to answer it anyway. I hope it is not against the rules.
A different way to think about it - foldr exists because the following recursive pattern is used often:
-- Example 1: Sum up numbers
summa :: Num a => [a] -> a
summa [] = 0
summa (x:xs) = x + suma xs
Taking the product of numbers or even reversing a list looks structurally very similar to the previous recursive function:
-- Example 2: Reverse numbers
reverso :: [a] -> [a]
reverso [] = []
reverso (x:xs) = x `op` reverso xs
where
op = (\curr acc -> acc ++ [curr])
The structure in the above examples only differs in the initial value (0 for summa and [] for reverso) along with the operator between the first value and the recursive call (+ for summa and (\q qs -> qs ++ [q]) for reverso). So the function structure for the above examples can be generally seen as
-- Generic function structure
foo :: (a -> [a] -> [a]) -> [a] -> [a] -> [a]
foo op init_val [] = init_val
foo op init_val (x:xs) = x `op` foo op init_val xs
To see that this "generic" foo works, we could now rewrite reverso by using foo and passing it the operator, initial value, and the list itself:
-- Test: reverso using foo
foo (\curr acc -> acc ++ [curr]) [] [1,2,3,4]
Let's give foo a more generic type signature so that it works for other problems as well:
foo :: (a -> b -> b) -> b -> [a] -> b
Now, getting back to your question - we could write filter like so:
-- Example 3: filter
filtero :: (a -> Bool) -> [a] -> [a]
filtero p [] = []
filtero p (x:xs) = x `filterLogic` (filtero p xs)
where
filterLogic = (\curr acc -> if (p curr) then curr:acc else acc)
This again has a very similar structure to summa and reverso. Hence, we should be able to use foo to rewrite it. Let's say we want to filter the even numbers from the list [1,2,3,4]. Then again we pass foo the operator (in this case filterLogic), initial value, and the list itself. filterLogic in this example takes a p function, called a predicate, which we'll have to define for the call:
let p = even in foo (\curr acc -> if (p curr) then curr:acc else acc) [] [1,2,3,4]
foo in Haskell is called foldr. So, we've rewritten filter using foldr.
let p = even in foldr (\curr acc -> if (p curr) then curr:acc else acc) [] [1,2,3,4]
So, filter can be written with foldr as we've seen:
-- Solution 1: filter using foldr
filtero' :: (a -> Bool) -> [a] -> [a]
filtero' p xs = foldr (\curr acc -> if (p curr) then curr:acc else acc) [] xs
As for map, we could also write it as
-- Example 4: map
mapo :: (a -> b) -> [a] -> [b]
mapo f [] = []
mapo f (x:xs) = x `op` (mapo f xs)
where
op = (\curr acc -> (f curr) : acc)
which therefore can be rewritten using foldr. For example, to multiply every number in a list by two:
let f = (* 2) in foldr (\curr acc -> (f curr) : acc) [] [1,2,3,4]
So, map can be written with foldr as we've seen:
-- Solution 2: map using foldr
mapo' :: (a -> b) -> [a] -> [b]
mapo' f xs = foldr (\curr acc -> (f curr) : acc) [] xs
Your solution almost works .)
The problem is that you've got two differend bindings for x in both your functions (Inside the patternmatching and inside your lambda expression), therefore you loose track of the first Element.
map' :: (a -> b) -> [a] -> [b]
map' f [] = []
map' f (x:xs) = foldr (\x xs -> (f x):xs) [] (x:xs)
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p (x:xs) = foldr (\x xs -> if p x then x:xs else xs ) [] (x:xs)
This should to the trick :). Also: you can write your functions pointfree style easily.
*Main> :{
*Main| map' :: (a -> b) -> [a] -> [b]
*Main| map' = \f -> \ys -> (foldr (\x -> \acc -> f x:acc) [] ys)
*Main| :}
*Main> map' (^2) [1..10]
[1,4,9,16,25,36,49,64,81,100]
*Main> :{
*Main| filter' :: (a -> Bool) -> [a] -> [a]
*Main| filter' = \p -> \ys -> (foldr (\x -> \acc -> if p x then x:acc else acc) [] ys)
*Main| :}
*Main> filter' (>10) [1..100]
In the above snippets acc refers to accumulator and x refers to the last element.
Everything is correct in your lambda expressions. The problem is you are missing the first element in the list. If you try,
map' f (x:xs) = foldr (\x xs -> f x:xs) [] (x:xs)
then you shouldn't miss the first element anymore. The same logic applies to filter.
filter' p (x:xs) = foldr(\ y xs -> if p y then y:xs else xs) [] (x:xs)

Resources