Map and Filter, Haskell - haskell

Hi I was wondering how to use the map and filter function in haskell to get the amount of a number in the list, That was confusing sorry here's an example.
let a = [[1,2,1,2,1,1,1],[1,2],[3,4],[3,2]]
And I want use map to find out how many 1s are in each sub-list so the outcome would be
[5,1,0,0]
Any idea how to do it, I'm guessing its easy and im just missing something, cheers, my approach is
let ones = map(\x length (filter (\z -> z == 1)x) )a
but this is getting errors

First get the filter function:
((==) 1)
This will filter all other elements than 1 from a list:
filter ((==) 1)
Then combine it with the length function through function composition:
(length . filter ((==) 1))
Finally, map the array of lists with that function and you're done!
map (length . filter ((==) 1))

Break the problem into small steps.
Step 1. Count the number of 1s in a list. Make a function count1s :: [Int] -> Int using length and filter.
Step 2. Use map to apply count1s to each list in the outer list.

You wrote:
let ones = map(\x length (filter (\z -> z == 1)x) )a
Very good attempt, and almost correct! Let's paste it into GHCi, it spouts back:
<interactive>:9:35: Parse error in pattern: \ z -> z == 1
So what does this mean? This means that it thinks it's looking at a pattern and that it's failed to read it (parsing its text). If we just look at that thing, it's not a pattern! Why does it think it's looking at a pattern?
Because of the earlier \x which was not followed by a ->. In the arguments of a function literal, you're allowed to pattern-match! You can write \(y:_) x -> y + x and that will be the same as (+) . head, taking the head of one list and adding it to the second number provided.
Inserting it we get:
let ones = map(\x -> length (filter (\z -> z == 1)x) )a
Which gives a further error:
<interactive>:10:55: Not in scope: ‘a’
This is because I forgot to explicitly define a, so it's easy to fix:
let ones a = map(\x -> length (filter (\z -> z == 1)x) )a
Compiles, and then:
Prelude> ones [[1,2,1,2,1,1,1],[1,2],[3,4],[3,2]]
[5,1,0,0]
as desired. But we're not done yet, let's simplify!
First off there is \z -> z == 1 which is easier written using operator sections as (1 ==). I would recommend always putting in that space so that it looks a little extra "incomplete".
Then \x -> length (filter (1 ==) x) is a little wordy too, we can instead use the function composition operator . to write this as length . filter (1 ==). If you get confused about precedence here, remember that parentheses always happen first, then functions, then operators... so this is (.) length (filter (1 ==)) if you really wrote it out.
Once you have that, give it a name and a type signature in a source file!
countOnes :: (Eq a, Num a) => [a] -> Int
countOnes = length . filter (1 ==)
Then I would write map countOnes wherever you're actually using this code.

Related

Redefining the drop function in terms of filter or map

I have a homework where I need to redefine the drop function in terms of the map or filter function.
drop n (:xs) = drop (n-1) (xs)
drop 3 [1,2,3,4,5] = [4,5]
I have an idea but I'm not sure how to implement it. First you zip the elements of the list (say xs) with [1..] and you get elements of the list paired with these numbers (say (x,y)). Then you somehow try to filter these pairs in such a way that y would be greater than 3.
Then you print out the elements of x from the filtered pairs.
But I struggle to put this idea into code. Any help I can get or suggestions about the idea would be much appreciated.
You have the exact right idea. It's a three step process: (1) zip with an enumerator of some kind, (2) filter based on the index, and (3) map to get rid of the enumerator. The code representing that would look something like this
drop :: Int -> [a] -> [a]
drop n xs = map snd . filter (\(i, _) -> i > n) . zip [1..] $ xs
where snd is the Prelude function defined as
snd :: (a, b) -> b
snd (a, b) = b

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.

Haskell - using Until on a list

I've been trying to do a function that creates a list of n numbers ([1...n]) using an until. So far I haven't found any examples of until manipulating lists and I've been improvising:
sequence Int -> [Int]
sequence x = until (== x) (++ [ +1 ]) [1]
But keep getting the Syntax error in expression (unexpected token) error
I know I could simply use a [1..n] to create the list, but I really want to make this work out. Thanks in advance for any help.
Take note of the type of until:
until :: (a -> Bool) -> (a -> a) -> a -> a
For your case, a is [Int], so everything has to take a list as input and return a list.
sequence x = until (\y -> last y == x) (\y -> y ++ [last y + 1]) [1]
The predicate takes a list and checks if its last element is equal to x.
The modifier takes a list and adds a new element to the end, with that new element being one greater than the last element of the list.
This is not very efficient, as you are continually working with the wrong end of the list. You can make it a little more efficient by building the list backwards, then reversing it at the end. (Since we are guaranteed to be using non-empty lists, I use head in place of pattern matching for simplicity.)
sequence x = reverse $ until ((== x) . head) (\y -> (head y + 1) : y) [1]
or build the list down from x to 1:
sequence x = until ((==1) . head) (\y -> head y-1 : y) [x]

Haskell, passing a function to filter in one line?

I want to filter everything that is not divisible by 3 from a list in Haskell, this is technically what I want to do
filter (`mod` 3) [1..100]
The problem is, mod x 3 won't return a boolean value. Is there a way to do this in one line? or am I forced to write another function which returns a boolean value? I've read about curried functions, but I'm not sure if its possible to do this because if I used (==) a b and a is a function, it just wouldn't work out.
That is what function composition is for:
filter ((== 0) . (`mod` 3)) [1..100]
As ever, contemplate the types of the involved functions until everything feels natural.
you can use dot notation
filter ((== 0) . (`mod` 3)) [1..100]
this generates
[3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99]
The type signature of dot is as follows:
(.) :: (b -> c) -> (a -> b) -> a -> c
If you want to define it in one line and don't want to write another function (which is going to be used in just one place anyway), the easiest way is to define lambda function:
filter (\x -> x `mod` 3 == 0) [1..100]
Point-free style suggested in other answers can sometimes lead to "hard to read" expressions when the auxiliary function is more complex then this. Especially for a beginner.
You can also use a list comprehension:
[x | x <- [1..100], (x `mod` 3) == 0]
An alternative version, using streams:
takeWhile (<=100) $ map (*3) [1..]

Error when trying to use function composition in Haskell

I have just began recently to learn Haskell, more specifically on the topics of function composition, partial functions, maps, filters and sectioning. On one of the exercises am asked to modify the twoFilters function by using function composition.
I have read a few wikis on . but am having quite a hard time getting it to work correctly. As i understand it, it works by performing the functions b . a on alphabetical order and returning the result. In other words x = foo a and then foo b of x. However after applying several "variations/possibilities" with the bellow two filters functions i cant get it to compile due to errors.
greaterThanOne :: Int -> Bool
greaterThanOne = (>1)
lessThanTen :: Int -> Bool
lessThanTen = (<10)
twoFilters :: [Int] -> [Int]
twoFilters xs= filter lessThanTen (filter greaterThanOne xs)
These two being the unsuccessful attempts I had most confidence on;
twoFilters xs = filter (lessThanTen . greaterThanOne xs)
twoFilters xs = filter (lessThanTen xs . greaterThanOne xs)
Where on the reasoning am I going wrong?
The attempts you were confident about are a simple failure in your logic: the dot operator works like this:
(f.g)(x) = f(g(x))
So, trying to compute an example of 5 gives:
lessThanThen(greaterThanOne(5)) = lessThanTen(True) -- that can't be right, can it???
What you want is a lambda and &&:
filter (\x-> (lessThanThen x) && greaterThanOne(x))
Alternatively, you can use two filters:
filter lessThanTen . filter greaterThanOne $
Enter the wonderful world of Applicative Functors:
import Control.Applicative
greaterThanOne = (>1)
lessThanTen = (<10)
twoFilters = filter ((&&) <$> greaterThanOne <*> lessThanTen)
twoFilters [1,2,3,4,5,6,7,8,9,10]
-- [2,3,4,5,6,7,8,9]
Read Learn you a Haskell - Applicative Functors for a detailed explanation.
You can't compose those two functions like this. f . g works like composition in maths, i.e. is equivalent to f(g(x)). That means the outer function must take an argument of a type that inner function returns, in your case the outer function would have to be Bool -> Bool.
You can write your twoFilters using composition operator like this:
twoFilters = (filter lessThanTen) . (filter greaterThanOne)
(.) expects a function which takes one argument and returns a value, but you pass it a Bool value in:
lessThanTen . greaterThanOne xs
which is wrong.
Here:
lessThanTen xs . greaterThanOne xs
you're trying to compose two Bool values, but you should've composed two functions which return Bool values.
One issue it that function application has highest precedence. So lessThanTen . greaterThanOne xs tries to compose lessThanTen with the result of greaterThanOne xs (which doesn't work to start with, the function works on integers, not on lists thereof). Likewise, lessThanTen xs. greaterThanOne xs tries to compose the results of those function calls (assuming they'd make sense in the first place), not the functions themself.
Another problem is a misunderstanding of . - (f . g) x is equivalent to f (g x), i.e. the result of the first function is the argument for the second. So the type of g must be (a -> b) and the type of f must be (b -> c) (both b are the same type variable!). What you want to apply both functions to the same argument and join the results with &&. There's no existing functions for this as far as I know (at least Hoogle didn't find anything for (a -> Bool) -> (a -> Bool) -> a -> Bool). You'll have to make your own:
both f g x = f x && g x
Alternatively, you coudl just stick to filtering twice (which isn't as bad as it sounds thanks to lazy evaluation) - filter (>1) $ filter (<10) xs.
As i understand it, it works by performing the functions b . a on alphabetical order and returning the result. In other words x = foo a and then foo b of x
This could be written in Haskell as
let x = foo a in
foo b x
(where does foo come from?) but the correct
(b . a) x = let y = a x in
b y
Or, shorter:
(b . a) x = b (a x)
Now, filter lessThanTen (filter greaterThanOne xs) has a similar shape to the right side of this definition, if you remember you could write it as (filter lessThanTen) ((filter greaterThanOne) xs):
((filter lessThanTen) . (filter greaterThanOne)) xs
Presumably what you actually want is filter ??? xs, but that should be enough to go on with.
You have it almost right. I find the easiest way to start learning function composition with . is to use $ first instead.
So you have a list
twoFilters xs = xs
You want to filter by greaterThanOne
twoFilters xs = filter greaterThanOne $ xs
You additionally want to filter by lessThanTen
twoFilters xs = filter lessThanTen $ filter greaterThanOne $ xs
Now move from left to right, replacing all $s with . except for the last $
twoFilters xs = filter lessThanTen . filter greaterThanOne $ xs
You could use parenthesis instead of $ now:
twoFilters xs = (filter lessThanTen . filter greaterThanOne) xs
Or just define the function pointfree:
twoFilters = filter lessThanTen . filter greaterThanOne
The parenthesized version is the most important, I think. It shows that you fuse the two partially-applied functions filter lessThanTen and filter greaterThanOne into one mega-filtering function, with . and then you apply the list to it. You need to parenthesize them because . binds less tightly than function application via whitespace (space can be considered an uber-high-fixity version of $). Remember, when you use ., you are fusing two functions together to form one mega-function.
It is relevant to inspect the type signature of .
(.) :: (b -> c) -> (a -> b) -> a -> c
The functions you feed it have to "line up" with very particular type signatures (they have to be compatible for fusing). But honestly, the key is learning to recognize when function application (with space) is binding more tightly than you intend and messing up the type signatures of functions you are trying to compose. That's how it was for me, anyways.

Resources