Haskell Pattern Matching Problem - haskell

Current Code
Hi I have a function like this:
jj::[Int]->[Int]
jj xs = [x|x<-xs,x `mod` 2 ==0]
For the input [1..20] it gives me as output :
[2,4,6,8,10,12,14,16,18,20] -> only the values divisible by 2
What I require
If list value is dividable by 2, it is interpreted as 0 and otherwise as 1:
Input : [243,232,243]
Output : [1,0,1]

Surely you just want map:
jj::[Int]->[Int]
jj xs = map (`mod` 2) xs
Due to currying
map (`mod` 2) :: [Int] -> [Int]
is exactly the function we want, so we can just do:
jj::[Int]->[Int]
jj = map (`mod` 2)
Both yield:
*Main> jj [2,4,5,6,8,9]
[0,0,1,0,0,1]

If you want the [] syntax (aka. the list comprehension), you can say
jj::[Int]->[Int]
jj xs = [x `mod` 2 | x<-xs]
which is equivalent to MGwynne's map solution.

Look at the following functions:
map :: (a -> b) -> [a] -> [b]
fmap :: (Functor f) => (a -> b) -> f a -> f b
where a list is an instance of the typeclass functor. You'll need a function of type Int -> Int that does your transformation.
jj :: (Functor f, Integral i) => f i -> f i
jj = fmap (`mod` 2)
(For lists, both map and fmap do the same thing. fmap is a generalization of map)

The recursive way:
dividablelist :: [Int] -> [Int]
dividablelist [] = []
dividablelist (x:xs) = mod x 2 : dividablelist xs

Related

apply a function n times to the n-th item in a list in haskell

I want a higher-order function, g, that will apply another function, f, to a list of integers such that
g = [f x1, f(f x2), f(f(f x3)), … , f^n(xn)]
I know I can map a function like
g :: (Int -> Int) -> [Int] -> [Int]
g f xs = map f xs
and I could also apply a function n-times like
g f xs = [iterate f x !! n | x <- xs]
where n the number of times to apply the function. I know I need to use recursion, so I don't think either of these options will be useful.
Expected output:
g (+1) [1,2,3,4,5] = [2,4,6,8,10]
You can work with explicit recursion where you pass each time the function to apply and the tail of the list, so:
g :: (Int -> Int) -> [Int] -> [Int]
g f = go f
where go _ [] = []
go fi (x:xs) = … : go (f . fi) xs
I here leave implementing the … part as an exercise.
Another option is to work with two lists, a list of functions and a list of values. In that case the list of functions is iterate (f .) f: an infinite list of functions that can be applied. Then we can implement g as:
g :: (Int -> Int) -> [Int] -> [Int]
g f = zipWith ($) (iterate (f .) f)
Sounds like another use for foldr:
applyAsDeep :: (a -> a) -> [a] -> [a]
applyAsDeep f = foldr (\x xs -> f x : map f xs) []
λ> applyAsDeep (+10) [1,2,3,4,5]
[11,22,33,44,55]
If you want to go a bit overkill ...
import GHC.Exts (build)
g :: (a -> a) -> [a] -> [a]
g f xs0 =
build $ \c n ->
let go x r fi = fi x `c` r (f . fi)
in foldr go (const n) xs0 f

Apply a Function to every element in a list

I've created a function m such that
m "abc" "def" == "bcd"
and I would like to create another function that uses m to generate the output ["bcd","efg","hia"] when given the input ["abc","def","ghi"]
The definition of m is
m :: [a] -> [a] -> [a]
m str1 str2 = (drop 1 str1) ++ (take 1 str2)
You can make use of zipWith :: (a -> b -> c) -> [a] -> [b] -> [c] here where you take the entire list as first parameter, and tail (cycle l) as second parameter (with l the list):
combine :: [a] -> [a]
combine l = zipWith m l (tail (cycle l))
zipWith will enumerate concurrently on both lists and each time call m with an element of the first and the second list. For example:
Prelude> combine ["abc","def","ghi"]
["bcd","efg","hia"]
You can append the first element to the end to simulate a wrap-around, then zip the list with its tail to get tuples of each element, then map it:
f :: [[a]] -> [[a]]
f [] = []
f l#(x:xs) = map (\(a, b) -> m a b) $ zip wrapped (tail wrapped)
where wrapped = l ++ [x]
Alternatively, you can use uncurry:
f :: [[a]] -> [[a]]
f [] = []
f l#(x:xs) = map (uncurry m) $ zip wrapped (tail wrapped)
where wrapped = l ++ [x]
import Data.List.HT (rotate)
m2 :: [[a]] -> [[a]]
m2 list = zipWith m list (rotate 1 list)
where m is yours.
You can make it point free in a couple of ways.
Here's using the Applicative style,
m2 :: [[a]] -> [[a]]
m2 = zipWith m <$> id <*> (rotate 1)
which can read as m2 is the function that passes its argument to id and rotate 1 respectively, and then those results to zipWith m.
Here's using the Monadic style,
import Control.Monad (ap)
m2 :: [[a]] -> [[a]]
m2 = zipWith m `ap` rotate 1
which is imho a bit less clear, in this case; you can read it as m2 passes its argument to both zipWith m and rotate 1 and then feeds the result of the latter to the the result of the former.
Honestly, I like the other answer a bit more, as it avoids importing rotate and gets the same effect with tail . cycle.

Haskell concat / filter according specific rules

According to following rules, I tried to solve the following problem:
No definition of recursion
No List of Comprehension
Only Prelude-Module is allowed.
Now I have to implement higher-order for concat and filter.
Im at this point:
concat' :: [[a]] -> [a]
concat' a = (concat a)
filter' :: (a -> Bool) -> [a] -> [a]
filter' p [] = []
filter' p (x:xs)
| p x = x : filter p xs
| otherwise = filter p xs
The concat function is working (nothing special so far) -> Is that a defined recursion? I mean I use the predefined concat from standard-prelude but myself I don't define it - or am I wrong?
For the filter, the function I've looked up the definition of standard prelude but that's either not working and it contains a definition of recursion.
I'm supposing the concat and filter functions should be avoided. Why would we need to implement concat and filter if they're already available? So try implementing them from scratch.
We can use folding instead of recursion and list comprehensions. The below solutions use the function foldr.
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
concat' :: [[a]] -> [a]
concat' = foldr (++) []
filter' :: (a -> Bool) -> [a] -> [a]
filter' p = foldr (\x acc -> if p x then x:acc else acc) []
Examples:
main = do
print $ concat' ["A", "B", "CAB"] -- "ABCAB"
print $ filter' (\x -> x `mod` 2 == 0) [1..9] -- [2, 4, 6, 8]
You may do as follows;
concat' :: Monad m => m (m b) -> m b
concat' = (id =<<)
filter' p = ((\x-> if p x then [x] else []) =<<)
=<< is just flipped version of the monadic bind operator >>=.
filter' (< 10) [1,2,3,10,11,12]
[1,2,3]

Adding predicate to a map function

Completely new to Haskell and learning through Learn Haskell the greater good.
I am looking at the map function
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
is it possible to add a predicate to this? for example, to only map to every other element in the list?
You can code your own version of map to apply f only to even (or odd) positions as follows. (Below indices start from 0)
mapEven :: (a->a) -> [a] -> [a]
mapEven f [] = []
mapEven f (x:xs) = f x : mapOdd f xs
mapOdd :: (a->a) -> [a] -> [a]
mapOdd f [] = []
mapOdd f (x:xs) = x : mapEven f xs
If instead you want to exploit the library functions, you can do something like
mapEven :: (a->a) -> [a] -> [a]
mapEven f = map (\(flag,x) -> if flag then f x else x) . zip (cycle [True,False])
or even
mapEven :: (a->a) -> [a] -> [a]
mapEven f = map (uncurry (\flag -> if flag then f else id)) . zip (cycle [True,False])
If you want to filter using an arbitrary predicate on the index, then:
mapPred :: (Int -> Bool) -> (a->a) -> [a] -> [a]
mapPred p f = map (\(i,x) -> if p i then f x else x) . zip [0..]
A more direct solution can be reached using zipWith (as #amalloy suggests).
mapEven :: (a->a) -> [a] -> [a]
mapEven f = zipWith (\flag x -> if flag then f x else x) (cycle [True,False])
This can be further refined as follows
mapEven :: (a->a) -> [a] -> [a]
mapEven f = zipWith ($) (cycle [f,id])
The "canonical" way to perform filtering based on positions is to zip the sequence with the naturals, so as to append an index to each element:
> zip [1, 1, 2, 3, 5, 8, 13] [0..]
[(1,0),(1,1),(2,2),(3,3),(5,4),(8,5),(13,6)]
This way you can filter the whole thing using the second part of the tuples, and then map a function which discards the indices:
indexedFilterMap p f xs = (map (\(x,_) -> f x)) . (filter (\(_,y) -> p y)) $ (zip xs [0..])
oddFibsPlusOne = indexedFilterMap odd (+1) [1, 1, 2, 3, 5, 8, 13]
To be specific to you question, one might simply put
mapEveryOther f = indexedFilterMap odd f
You can map with a function (a lambda is also possible):
plusIfOdd :: Int -> Int
plusIfOdd a
| odd a = a
| otherwise = a + 100
map plusIfOdd [1..5]
As a first step, write the function for what you want to do to the individual element of the list:
applytoOdd :: Integral a => (a -> a) -> a -> a
applytoOdd f x = if odd x
then (f x)
else x
So applytoOdd function will apply the function f to the element if the element is odd or else return the same element if it is even. Now you can apply map to that like this:
λ> let a = [1,2,3,4,5]
λ> map (applytoOdd (+ 100)) a
[101,2,103,4,105]
Or if you want to add 200 to it, then:
λ> map (applytoOdd (+ 200)) a
[201,2,203,4,205]
Looking on the comments, it seems you want to map based on the index position. You can modify your applytoOdd method appropriately for that:
applytoOdd :: Integral a => (b -> b) -> (a, b) -> b
applytoOdd f (x,y) = if odd x
then (f y)
else y
Here, the type variable a corresponds to the index element. If it's odd you are applying the function to the actual element of the list. And then in ghci:
λ> map (applytoOdd (+ 100)) (zip [1..5] [1..])
[101,2,103,4,105]
λ> map (applytoOdd (+ 200)) (zip [1..5] [1..])
[201,2,203,4,205]
Or use a list comprehension:
mapOdd f x = if odd x then f x else x
[ mapOdd (+100) x | x <- [1,2,3,4,5]]
I'm glad that you're taking the time to learn about Haskell. It's an amazing language. However it does require you to develop a certain mindset. So here's what I do when I face a problem in Haskell. Let's start with your problem statement:
Is it possible to add a predicate to the map function? For example, to only map to every other element in the list?
So you have two questions:
Is it possible to add a predicate to the map function?
How to map to every other element in the list?
So the way people think in Haskell is via type signatures. For example, when an engineer is designing a building she visualizes how the building should look for the top (top view), the front (front view) and the side (side view). Similarly when functional programmers write code they visualize their code in terms of type signatures.
Let's start with what we know (i.e. the type signature of the map function):
map :: (a -> b) -> [a] -> [b]
Now you want to add a predicate to the map function. A predicate is a function of the type a -> Bool. Hence a map function with a predicate will be of the type:
mapP :: (a -> Bool) -> (a -> b) -> [a] -> [b]
However, in your case, you also want to keep the unmapped values. For example mapP odd (+100) [1,2,3,4,5] should result in [101,2,103,4,105] and not [101,103,105]. Hence it follows that the type of the input list should match the type of the output list (i.e. a and b must be of the same type). Hence mapP should be of the type:
mapP :: (a -> Bool) -> (a -> a) -> [a] -> [a]
It's easy to implement a function like this:
map :: (a -> Bool) -> (a -> a) -> [a] -> [a]
mapP p f = map (\x -> if p x then f x else x)
Now to answer your second question (i.e. how to map to every other element in the list). You could use zip and unzip as follows:
snd . unzip . mapP (odd . fst) (fmap (+100)) $ zip [1..] [1,2,3,4,5]
Here's what's happening:
We first zip the index of each element with the element itself. Hence zip [1..] [1,2,3,4,5] results in [(1,1),(2,2),(3,3),(4,4),(5,5)] where the fst value of each pair is the index.
For every odd index element we apply the (+100) function to the element. Hence the resulting list is [(1,101),(2,2),(3,103),(4,4),(5,105)].
We unzip the list resulting in two separate lists ([1,2,3,4,5],[101,2,103,4,105]).
We discard the list of indices and keep the list of mapped results using snd.
We can make this function more general. The type signature of the resulting function would be:
mapI :: ((Int, a) -> Bool) -> (a -> a) -> [a] -> [a]
The definition of the mapI function is simple enough:
mapI :: ((Int, a) -> Bool) -> (a -> a) -> [a] -> [a]
mapI p f = snd . unzip . mapP p (fmap f) . zip [1..]
You can use it as follows:
mapI (odd . fst) (+100) [1,2,3,4,5]
Hope that helps.
Is it possible to add a predicate to this? for example, to only map to every other element in the list?
Yes, but functions should ideally do one relatively simple thing only. If you need to do something more complicated, ideally you should try doing it by composing two or more functions.
I'm not 100% sure I understand your question, so I'll show a few examples. First: if what you mean is that you only want to map in cases where a supplied predicate returns true of the input element, but otherwise just leave it alone, then you can do that by reusing the map function:
mapIfTrue :: (a -> Bool) -> (a -> a) -> [a] -> [a]
mapIfTrue pred f xs = map step xs
where step x | pred x = f x
| otherwise = x
If what you mean is that you want to discard list elements that don't satisfy the predicate, and apply the function to the remaining ones, then you can do that by combining map and filter:
filterMap :: (a -> Bool) -> (a -> b) -> [a] -> [b]
filterMap pred f xs = map f (filter pred xs)
Mapping the function over every other element of the list is different from these two, because it's not a predicate over the elements of the list; it's either a structural transformation of the list of a stateful traversal of it.
Also, I'm not clear whether you mean to discard or keep the elements you're not applying the function to, which would imply different answers. If you're discarding them, then you can do it by just discarding alternate list elements and then mapping the function over the remaining ones:
keepEven :: [a] -> [a]
keepEven xs = step True xs
where step _ [] = []
step True (x:xs) = x : step False xs
step False (_:xs) = step True xs
mapEven :: (a -> b) -> [a] -> [b]
mapEven f xs = map f (keepEven xs)
If you're keeping them, one way you could do it is by tagging each list element with its position, filtering the list to keep only the ones in even positions, discard the tags and then map the function:
-- Note: I'm calling the first element of a list index 0, and thus even.
mapEven :: (a -> a) -> [a] -> [a]
mapEven f xs = map aux (filter evenIndex (zip [0..] xs))
where evenIndex (i, _) = even i
aux (_, x) = f x
As another answer mentioned, zip :: [a] -> [b] -> [(a, b)] combines two lists pairwise by position.
But this is the general philosophy: to do a complex thing, use a combination of general-purpose generic functions. If you're familiar with Unix, it's similar to that.
Another simple way to write the last one. It's longer, but keep in mind that evens, odds and interleave all are generic and reusable:
evens, odds :: [a] -> [a]
evens = alternate True
odds = alternate False
alternate :: Bool -> [a] -> [a]
alternate _ [] = []
alternate True (x:xs) = x : alternate False xs
alternate False (_:xs) = alternate True xs
interleave :: [a] -> [a] -> [a]
interleave [] ys = ys
interleave (x:xs) ys = x : interleave ys xs
mapEven :: (a -> a) -> [a] -> [a]
mapEven f xs = interleave (map f (evens xs)) (odds xs)
You can't use a predicate because predicates operate on list values, not their indices.
I quite like this format for what you're trying to do, since it makes the case handling quite clear for the function:
newMap :: (t -> t) -> [t] -> [t]
newMap f [] = [] -- no items in list
newMap f [x] = [f x] -- one item in list
newMap f (x:y:xs) = (f x) : y : newMap f xs -- 2 or more items in list
For example, running:
newMap (\x -> x + 1) [1,2,3,4]
Yields:
[2,2,4,4]

Haskell - Counting how many times each distinct element in a list occurs

I'm new to Haskell and am just trying to write a list comprehension to calculate the frequency of each distinct value in a list, but I'm having trouble with the last part..
So far i have this:
frequency :: Eq a => [a] -> [(Int,a)]
frequency list = [(count y list,y) | y <- rmdups ]
Something is wrong with the last part involving rmdups.
The count function takes a character and then a list of characters and tells you how often that character occurs, the code is as follows..
count :: Eq a => a -> [a] -> Int
count x [] = 0
count x (y:ys) | x==y = 1+(count x ys)
| otherwise = count x ys
Thank-you in advance.
You could also use a associative array / finite map to store the associations from list elements to their count while you compute the frequencies:
import Data.Map (fromListWith, toList)
frequency :: (Ord a) => [a] -> [(a, Int)]
frequency xs = toList (fromListWith (+) [(x, 1) | x <- xs])
Example usage:
> frequency "hello world"
[(' ',1),('d',1),('e',1),('h',1),('l',3),('o',2),('r',1),('w',1)]
See documentation of fromListWith and toList.
I had to use Ord in instead of Eq because of the use of sort
frequency :: Ord a => [a] -> [(Int,a)]
frequency list = map (\l -> (length l, head l)) (group (sort list))
As requested, here's a solution using Control.Arrow:
frequency :: Ord a => [a] -> [(Int,a)]
frequency = map (length &&& head) . group . sort
This is the same function as ThePestest's answer, except
λ f g l -> (f l, g l)
is replaced with
-- simplified type signature
(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)
from Control.Arrow. If you want to avoid the import,
liftA2 (,) :: Applicative f => f a -> f b -> f (a, b)
works as well (using the Applicative instance of (->) r)
Assuming rmdups has the type
rmdups :: Eq a => [a] -> [a]
Then you're missing a parameter for it.
frequency :: Eq a => [a] -> [(Int,a)]
frequency list = [(count y list,y) | y <- rmdups list]
But the error you're getting would be helpful with diagnosis.
Your rmdups function is just nub from Data.List.
Replacing rmdups with nub list worked for me like a charm.
Hahahaha there is an rmdups on pg. 86 of Programming in Haskell by Graham Hutton. It is perfect and recursive. It is also handy in a great many situations.
Here is my one line rmdups and it produces the same results as nubor Hutton's.
rmdups ls = [d|(z,d)<- zip [0..] ls,notElem d $ take z ls]
It can well be used to count distinct elements of a list.
dl = "minimum-maximum"
[ (d,sum [1|x<-dl,d == x]) | d<-rmdups dl]
[('m',6),('i',3),('n',1),('u',2),('-',1),('a',1),('x',1)]

Resources