# Filter by a transformed list, then untransform the result

Both exercises have a common pattern of "filter by a transformed list, then untransform the result". See skip and localMaxima.

-- exercise 1
skips :: [a] -> [[a]]
skips xs = map (\n -> skip n xs) [1..(length xs)]

skip :: Integral n => n -> [a] -> [a]
skip n xs = map snd $filter (\x -> (fst x) mod n == 0) (zip [1..] xs) --exercise 2 isLocalMaximum :: Integral a => (a,a,a) -> Bool isLocalMaximum (a,b,c) = b > a && b > c sliding3 :: [a] -> [(a,a,a)] sliding3 xs@(a:b:c:_) = (a,b,c) : sliding3 (tail xs) sliding3 _ = [] localMaxima :: Integral a => [a] -> [a] localMaxima xs = map proj2$ filter isLocalMaximum (sliding3 xs)
where proj2 (_,b,_) = b

-- *Main> filter isLocalMaximum (sliding3 [1,5,2,6,3])
-- [(1,5,2),(2,6,3)]


My instincts say that I could implement both of these something like this:

localMaxima' :: Integral a => [a] -> [a]
localMaxima' xs = filterBy isLocalMaximum sliding3 xs


if only I could implement filterBy

filterBy :: (b -> Bool) -> ([a] -> [b]) -> [a] -> [a]
filterBy p f as = as'
where indexedAs = zipWith (,) [0..] as
indexedBs = zipWith (,) [0..] (f as)
indexedBs' = filter p indexedBs     -- doesn't typecheck; how can we teach p about the tuples?
indexes = map fst indexedBs
as' = map (\i -> snd (indexedAs !! i)) indexes


It's also slower than just writing out a fold. Is this all a bad idea? I've always considered fold a low level recursion operator and always try to structure in terms of higher level map and filter but maybe I am misunderstanding.

My Haskell level is: understand LYAH but not written much code.

This is a homework to CIS 194 (2013 version) (though I am not taking the class, I am working through the material on my own)

## Exercise 1

If you have a lambda (or any function) of type (a,b)->c, instead of writting it like this (\x->...), you can write it like this (\(x,y)->...). It will remove the need of calling fst like in your skip function. You should change the name skip too, because it already exist in the prelude and it's kinda unclear because they have different meaning. I would call it something like skipEvery

## Exercise 2

as is a keyword in Haskell, used for module importation. It will compile if you use it as a variable, but if you a text editor with syntax highlighting, it will be weird

My instincts say that I could implement both of these something like this:

localMaxima' :: Integral a => [a] -> [a]
localMaxima' xs = filterBy isLocalMaximum sliding3 xs


Your instinct wasn't wrong, but there is an alternative to filterBy, which is mapMaybe. The resulting code would be something like this

whenMaybe p x = if p x then Just x else Nothing
localMaxima' = mapMaybe (whenMaybe isLocalMaximum) . sliding3


You should use zip instead of zipWith (,), because both operations are equivalent