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] -&gt; [[a]]
skips xs = map (\n -&gt; skip n xs) [1..(length xs)]

skip :: Integral n =&gt; n -&gt; [a] -&gt; [a]
skip n xs = map snd $ filter (\x -&gt; (fst x) `mod` n == 0) (zip [1..] xs)


--exercise 2
isLocalMaximum :: Integral a =&gt; (a,a,a) -&gt; Bool
isLocalMaximum (a,b,c) = b &gt; a &amp;&amp; b &gt; c

sliding3 :: [a] -&gt; [(a,a,a)]
sliding3 xs@(a:b:c:_) = (a,b,c) : sliding3 (tail xs)
sliding3 _ = []

localMaxima :: Integral a =&gt; [a] -&gt; [a]
localMaxima xs = map proj2 $ filter isLocalMaximum (sliding3 xs)
  where proj2 (_,b,_) = b

-- *Main&gt; 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 =&gt; [a] -&gt; [a]
localMaxima' xs = filterBy isLocalMaximum sliding3 xs


if only I could implement filterBy

filterBy :: (b -&gt; Bool) -&gt; ([a] -&gt; [b]) -&gt; [a] -&gt; [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 -&gt; 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)-&gt;c, instead of writting it like this (\x-&gt;...), you can write it like this (\(x,y)-&gt;...). 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 =&gt; [a] -&gt; [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