Skip to content

Instantly share code, notes, and snippets.

@dustingetz
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dustingetz/099c242a29181295a724 to your computer and use it in GitHub Desktop.
Save dustingetz/099c242a29181295a724 to your computer and use it in GitHub Desktop.
-- Both exercises have a common pattern of "filter by a transformed list, then untransform the result".
-- Is there an idiomatic way to do this?
-- I am thinking like `filterBy :: (b -> Bool) -> (a -> b) -> [a] -> [b]`,
-- but i also need (b->a) and that's no better than what i already have
-- 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
@dustingetz
Copy link
Author

This is what my instincts were leading me towards, but i can't quite make it typecheck, and it is not very general since second parameter must be f :: [a] -> [b] rather than f :: a -> b

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
        indexes = map fst indexedBs
        as' = map (\i -> snd (indexedAs !! i)) indexes

-- the goal is to write something like this
localMaxima' :: Integral a => [a] -> [a]
localMaxima' xs = filterBy isLocalMaximum sliding3 xs
    Couldn't match type ‘b’ with ‘(Int, b)’
      ‘b’ is a rigid type variable bound by
          the type signature for
            filterBy :: (b -> Bool) -> ([a] -> [b]) -> [a] -> [a]
          at hw3.hs:26:13
    Expected type: [b]
      Actual type: [(Int, b)]
    Relevant bindings include
      indexedBs' :: [b] (bound at hw3.hs:30:9)
      indexedBs :: [(Int, b)] (bound at hw3.hs:29:9)
      f :: [a] -> [b] (bound at hw3.hs:27:12)
      p :: b -> Bool (bound at hw3.hs:27:10)
      filterBy :: (b -> Bool) -> ([a] -> [b]) -> [a] -> [a]
        (bound at hw3.hs:27:1)
    In the second argument of ‘filter’, namely ‘indexedBs’
    In the expression: filter p indexedBs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment