Skip to content

Instantly share code, notes, and snippets.

@jvlmdr
Last active August 30, 2023 07:55
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 jvlmdr/1ff82f4fa31c9efa65f859f461e2c2a2 to your computer and use it in GitHub Desktop.
Save jvlmdr/1ff82f4fa31c9efa65f859f461e2c2a2 to your computer and use it in GitHub Desktop.
Four different Haskell implementations of filter
module Strain (keep, discard) where
keep :: (a -> Bool) -> [a] -> [a]
keep p = keep' where
keep' [] = []
keep' (x:xs) = (if p x then (x :) else id) $ keep' xs
discard :: (a -> Bool) -> [a] -> [a]
discard = keep . (not .)
module Strain (keep, discard) where
-- List comprehension.
keep :: (a -> Bool) -> [a] -> [a]
keep p xs = [x | x <- xs, p x]
discard :: (a -> Bool) -> [a] -> [a]
discard = keep . (not .)
module Strain (keep, discard) where
-- Tail recursion (breaks lazy evaluation).
keep :: (a -> Bool) -> [a] -> [a]
keep p = reverse . keep' [] where
keep' ys [] = ys
keep' ys (x:xs)
| p x = keep' (x:ys) xs
| otherwise = keep' ys xs
discard :: (a -> Bool) -> [a] -> [a]
discard = keep . (not .)
module Strain (keep, discard) where
import Data.Maybe (maybeToList)
keep :: (a -> Bool) -> [a] -> [a]
keep p = (maybeToList . justIf p =<<)
justIf :: (a -> Bool) -> a -> Maybe a
justIf p x
| p x = Just x
| otherwise = Nothing
discard :: (a -> Bool) -> [a] -> [a]
discard = keep . (not .)
module Strain (keep, discard) where
import Control.Monad (MonadPlus, guard)
mask :: MonadPlus f => (a -> Bool) -> a -> f a
mask p x = guard (p x) >> return x
keep :: (a -> Bool) -> [a] -> [a]
keep p = (>>= mask p)
discard :: (a -> Bool) -> [a] -> [a]
discard = keep . (not .)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment