In Data.List module there's inits function that turns for example, [1,2,3,4] -> [[],[1],[1,2],[1,2,3],[1,2,3,4]]
I'm trying to define similar function using recursion, however I can't think of a way doing in correct order. The closest I have gotten is the list backwards, result = [[],[4],[3,4],[2,3,4],[1,2,3,4]]:
inits' :: [Int] -> [[Int]]
inits' [] = [[]]
inits' (x:xs) = inits' xs ++ [(x:xs)]
I'm not exactly sure how I could create a list by appending one element at time in the correct order? Could someone point in right direction, or is it not possible to do via recursion?
The easiest thing to try for such a function is just looking at the desired result and “reverse-pattern-matching” on the RHS of the function equation.
You already have that with
inits' [] = [[]]
Now with inits (x:xs), for example inits (1:[2,3,4]), you know that the result should be [[],[1],[1,2],[1,2,3],[1,2,3,4]], which matches the pattern []:_. So
inits' (x:xs) = [] : _
Now, the simplest recursion would be to just call inits' again on xs, like
inits' (x:xs) = [] : inits' xs
however, that doesn't give the correct result: assuming the recursive call works correctly, you have
inits' (1:[2,3,4]) = [] : [[],[2],[2,3],[2,3,4]]
= [[],[],[2],[2,3],[2,3,4]]
The 1 is completely missing, obviously, because we didn't actually use it in the definition. We need to use it, in fact it should be prepended before all of the list-chunks in the recursive result. You can do that with map.
We can prepend the data of all the remaining inits, like for example:
inits' :: [a] -> [[a]]
inits' [] = [[]]
inits' (x:xs) = [] : map (x:) (inits' xs)
As a basecase we return a singleton list with an empty list when the input is an empty list.
In the recursive case, we first yield the empty list, followed by the inits' of the tail of the list, but all these elements are prepended with x (with map (x:)).
Then we have:
Prelude> inits' [1,4,2,5]
[[],[1],[1,4],[1,4,2],[1,4,2,5]]
Since (not in evaluation order):
inits' [1,4,2,5]
-> [] : map (1:) (inits' [4,2,5])
-> [] : map (1:) ([] : map (4:) (inits' [2,5]))
-> [] : map (1:) ([] : map (4:) ([] : map (2:) (inits' [5])))
-> [] : map (1:) ([] : map (4:) ([] : map (2:) ([] : map (5:) (inits' []))))
-> [] : map (1:) ([] : map (4:) ([] : map (2:) ([] : map (5:) [[]])))
-> [] : map (1:) ([] : map (4:) ([] : map (2:) ([] : [[5]])))
-> [] : map (1:) ([] : map (4:) ([] : map (2:) [[],[5]]))
-> [] : map (1:) ([] : map (4:) ([] : [[2],[2,5]]))
-> [] : map (1:) ([] : map (4:) [[],[2],[2,5]])
-> [] : map (1:) ([] : [[4],[4,2],[4,2,5]])
-> [] : map (1:) [[],[4],[4,2],[4,2,5]]
-> [] : [[1],[1,4],[1,4,2],[1,4,2,5]]
-> [[],[1],[1,4],[1,4,2],[1,4,2,5]]
I think you should change your function definition from:
inits' :: [Int] -> [[Int]]
to:
inits' :: [a] -> [[a]]
Since inits from Data.List is of type [a] -> [[a]], and it doesn't care whats actually in the list. It needs to be polymorphic and accept a list of any type.
Furthermore, since others have shown the most straightforward recursive approach, you can also use foldr here.
Here is the base code:
inits' :: [a] -> [[a]]
inits' = foldr (\x acc -> [] : (map (x:) acc)) [[]]
Where [[]] is the base case, just like in your function. For the actual recursive part, here is how it works with the call inits' [1, 2, 3, 4]:
Starts folding from the right at value 4, and creates [[], [4]]
Now on value 3, and creates [[], [3], [3, 4]
Now on value 2, and creates [[], [2], [2, 3], [2, 3, 4]]
Now on value 1, and creates [[], [1], [1, 2], [1, 2, 3], [1, 2, 3, 4]]
Which gives the final nested list required, similarily to the function call:
*Main> inits' [1,2,3,4]
[[],[1],[1,2],[1,2,3],[1,2,3,4]]
From the behavior described above, you just need to focus on [] : (map (x:) acc), where you map the current value x being folded into your accumulated list acc, while also prepending an empty list on each fold.
If you still have trouble understanding foldr, you can look at this minimal example of how the folding performs from the right:
foldr f x [a, b, c] = a `f` (b `f` (c `f` x))
and How does foldr work?
I am learning Haskell at the moment and have come to a bit of a standstill. I'm trying to write a function that takes a predicate p and a list xs and returns the list of those elements of xs which immediately follow an element which passes the predicate p. Here is what I have :
afterFilter :: (a -> Bool) -> [a] -> [a]
afterFilter x (y:ys) =
if x y
then (map head [ys])
else
afterFilter x (tail ys)
test input : afterFilter (<0) [-4,7,-4,-8,3,-3,-6,0,-9,-1]
output : [7]
The trick is to pull two elements out of the input list by pattern-matching two cons cells. If the first element passes the predicate, we stick the second on the output. But don't forget to stick the second element back on the input list when you make the recursive call.
afterFilter :: (a -> Bool) -> [a] -> [a]
afterFilter f [] = [] -- input list is empty
afterFilter f [x] = [] -- input list has only one element - no "next element" to return
afterFilter f (x:y:xs) =
let ys = afterFilter f (y:xs)
in (if f x then y:ys else rest)
However, a higher-level - and much more Haskellish - way to approach the problem would be to break it down into a pipeline of operations.
Pair up each item in the list with the element that follows it using zip, so we have a list of (element, next) pairs.
Use filter to drop the pairs for which element does not pass the predicate.
Use map to extract the next part of each surviving pair.
So the code looks like this:
pairWithSuccessors :: [a] -> [(a, a)]
pairWithSuccessors xs = zip xs (tail xs)
afterFilter :: (a -> Bool) -> [a] -> [a]
afterFilter p xs =
let withSuccessors = pairWithSuccessors xs (tail xs)
filtered = filter (\(element, next) -> p element) withSuccessors
filteredSuccessors = map (\(element, next) -> next) filtered
in filteredSuccessors
Or, written in point-free style:
afterFilter p = map snd . filter (p . fst) . pairWithSuccessors
Functions built with the composition operator . are read right-to-left: first pairWithSuccessors, then filter (p . fst), then map snd over the result.
GHC is good at working with lists: when compiled with optimisations, both approaches should produce roughly the same machine code - that is, there's no performance cost to the high-level solution
Following what you did, there are some strange things with your code :
The map head [ys] is very odd, and causes your function to stop : At the first element matching the predicate, your function returns a list containing its immediate successor and stops there. You still need to process the rest of the list.
Also, following your definition of the problem, each item which is a successor of an item passing the predicate should be on the resulting array. I may be wrong, but what I understood is that afterFilter (<0) [-1, -1, 1] should return [-1, 1].
However, you're discarding one element you didn't check for by calling tail ys : You checked for y, but not for head ys.
Finally, by adding the edge cases, here is what you get :
afterFilter :: (a -> Bool) -> [a] -> [a]
afterFilter _ [] = []
afterFilter _ [_] = []
afterFilter x (y:ys#(z:zs)) =
if x y
then z : afterFilter x ys
else
afterFilter x ys
Try:
afterFilter :: (a -> Bool) -> [a] -> [a]
afterFilter p [] = []
afterFilter p [_] = []
afterFilter p (x1:x2:xs)
| p x1 = x2:rest
| otherwise = rest
where rest = afterFilter p (x2:xs)
Or
afterFilter' :: (a -> Bool) -> [a] -> [a]
afterFilter' p xs = map snd $ filter (\(x, _) -> p x) $ zip xs (tail xs)
Or
afterFilter'' :: (a -> Bool) -> [a] -> [a]
afterFilter'' p xs = [y | (x, y) <- zip xs (tail xs), p x]
Here is my own implementation of nub (remove duplicates):
nub :: (Eq a) => [a] -> [a]
nub lista = nub_rec lista []
where
nub_rec :: (Eq a) => [a] -> [a] -> [a]
nub_rec [] acc = acc
nub_rec (x:xs) acc = nub_rec (filter (\y -> if y == x then False else True) xs) (x:acc)
I consider how to use foldr/foldl to implement nub, could you help me ? I can't see a way.
First, your implementation of nub is bit more complex than it needs to be (and it reverses the order of elements in the list). Here's a simpler one:
myNub :: Eq a => [a] -> [a]
myNub (x:xs) = x : filter (/= x) (myNub xs)
myNub [] = []
Now, if we want to use foldr to write a function that will output, not just an "aggregate" but a full list, it's useful to first have a look at the simplest foldr-based function that takes in a list and spits out a list:
myNoop :: [a] -> [a]
myNoop l = foldr (\ x xs -> x : xs) [] l
Given that, the filter must be inserted somewhere. Since I assume this is a homework, I'll leave that to the OP as an exercise :)
Solution only with filter and foldr without direct (or self) recursion:
removeDuplicates :: Eq a => [a] -> [a]
removeDuplicates = foldr (\z ys -> z : filter (/= z) ys) []
I'm trying to write a function named split that takes a list and returns a list of pairs of all the different possiblities to partition it, e.g.
split [4,3,6] = [([],[4,3,6]),([4],[3,6]),([4,3],[6]),([4,3,6],[])]
Now I wrote this
split :: [a] -> [([a],[a])]
split [] = [([],[])]
split (x:xs) = ([],(x:xs)):(zip (map (x:) (map fst split(xs))) (map snd split(xs)))
piece of code and Hugs and the interpreter of my choice gets me this
ERROR file:.\split.hs:3 - Type error in application
*** Expression : map snd split xs
*** Term : map
*** Type : (e -> f) -> [e] -> [f]
*** Does not match : a -> b -> c -> d
error message. What the heck am I doing wrong? Why would (map snd split xs) be of type
(a-> b -> c -> d)?
You've misplaced your parens. Try
split (x:xs) = ([],(x:xs)):(zip (map (x:) (map fst (split xs))) (map snd (split xs)))
Haskell doesn't use parenthesis for function calls in the same way as something like C and Java. When you write map fst split(xs) this is the same as map fst split xs, i.e. the compiler thinks that you are trying to call map with three parameters. Therefore you need to parenthise the call to split like this: map fst (split xs).
What you are effectively trying to write is a simple zipper for a list. The easiest way to implement it is
import Data.List (inits, tails)
split xs = zip (inits xs) (tails xs)
Here's an alternative definition:
splits :: [a] -> [(a, a)]
splits xs = map (flip splitAt xs) [0 .. length xs]
Admittedly, it's not very efficient, but at least it's concise :-)
Another version that's even shorter, and probably more efficient, using inits and tails from Data.List:
splits :: [a] -> [(a, a)]
splits xs = zip (inits xs) (tails xs)
Now let's have a little fun. We can write inits and tails as foldrs, where we use initsA and tailsA to represent what are known as the algebras of the folds:
inits :: [a] -> [[a]]
inits = foldr initsA [[]]
initsA :: a -> [[a]] -> [[a]]
initsA x xss = [] : map (x:) xss
tails :: [a] -> [[a]]
tails = foldr tailsA [[]]
tailsA :: a -> [[a]] -> [[a]]
tailsA x xss = (x : head xss) : xss
Using these algebras, we can further combine them:
splits :: [a] -> [([a], [a])]
splits = foldr splitsA [([], [])]
splitsA :: a -> [([a], [a])] -> [([a], [a])]
splitsA xy xyss = zip (initsA xy xss) (tailsA xy yss)
where (xss, yss) = unzip xyss
So now we have splits defined as a single foldr!
I am trying to start learning haskell, and a question came up.
Say, I have a function
countFilter :: (a -> Bool) -> [a] -> ([a], Int)
countFilter a z = case z of [] -> ([], 0);
(x:xs) -> (filter a z , length (filter a z))
It returns a list, all the items of which apply to a certain predicate and a length of that list, which is not relevant.
countFilter (<7) [1,2,4,7,11,8,2] will output ([1,2,4,2], 4).
How to create such an output: ([7,11,8], 4) using the same predicate (<7)?
If I understand your question correctly, you want to return all the elements that don't match the predicate (< 7) as the first element of the pair.
In that case you can simply use the not function to flip the resulting boolean.
I.e. create a new predicate (\x -> not (oldPred x)), or using function composition: (not . oldPred):
countFilter :: (a -> Bool) -> [a] -> ([a], Int)
countFilter f xs = (filter (not . f) xs, length (filter f xs))
Note that both filter and length can deal with empty lists, so you don't need to write a case yourself.
Alternatively, you can use the partition function to create the two lists, so that you don't filter the list twice:
import Data.List
countFilter :: (a -> Bool) -> [a] -> ([a], Int)
countFilter f xs = let (ys, zs) = partition (not . f) xs
in (ys, length zs)
It's probably possible to create an even more efficient version that doesn't use length, but I leave that as an exercise :-)