Filter pattern
is one of the frequently used patterns in functional programming. By using
filter pattern, you can filter elements from a sequence.
For example,
you want to
a. Remove all even numbers from a list
b. Remove all odd numbers from a list
c. Remove all numbers that are > 100
You implement
like below.
filterEx.hs
{- Remove all even numbers from a list -} removeEven :: [Integer] :: [Integer] removeEven [] = [] removeEven (x:xs) | odd x = x : removeEven xs | otherwise = removeEven xs {- Remove all odd numbers from a list -} removeOdd :: [Integer] :: [Integer] removeOdd [] = [] removeOdd (x:xs) | odd x = x : removeOdd xs | otherwise = removeOdd xs {- Remove all numbers that are > 100 -} removeGt100 :: [Integer] :: [Integer] removeGt100 [] = [] removeGt100 (x:xs) | (x < 100) = x : removeGt100 xs | otherwise = removeGt100 xs
Prelude> :load filterEx.hs [1 of 1] Compiling Main ( filterEx.hs, interpreted ) Ok, modules loaded: Main. *Main> *Main> removeEven [2, 5, 123, 45, 66, 21] [5,123,45,21] *Main> *Main> removeOdd [2, 5, 123, 45, 66, 21] [5,123,45,21] *Main> *Main> removeGt100 [2, 5, 123, 45, 66, 21] [2,5,45,66,21] *Main>
By using filter pattern, you can
implement the same functions like below.
filterEx.hs
isLt100 num = (num < 100) removeGt100 xs = filter isLt100 xs removeEven xs = filter odd xs removeOdd xs = filter even xs
Prelude> :load filterEx.hs [1 of 1] Compiling Main ( filterEx.hs, interpreted ) Ok, modules loaded: Main. *Main> *Main> removeEven [2, 5, 123, 45, 66, 21] [5,123,45,21] *Main> *Main> removeGt100 [2, 5, 123, 45, 66, 21] [2,5,45,66,21] *Main> *Main> removeOdd [2, 5, 123, 45, 66, 21] [2,66] *Main>
The
implementation for filter pattern looks like below.
filter :: (a -> Bool) -> [a] -> [a] filter _ [] = [] filter p (x:xs) | p x = x : filter p xs | otherwise = filter p xs
Example 1: Return an element from list that satisfies given
predicate.
ListUtil.hs
getElement :: (a -> Bool) -> [a] -> Maybe a getElement predicateFun list = myFilter predicateFun list myFilter :: (a -> Bool) -> [a] -> Maybe a myFilter p [] = Nothing myFilter p (x:xs) | p x = Just x | otherwise = myFilter p xs
Prelude> :load ListUtil.hs [1 of 1] Compiling Main ( ListUtil.hs, interpreted ) Ok, modules loaded: Main. *Main> *Main> getElement even [1, 2, 3, 4, 5] Just 2 *Main> getElement odd [ 2, 6, 3, 4, 5] Just 3 *Main> getElement odd [ 2, 6] Nothing *Main> getElement odd [] Nothing *Main> :t getElement getElement :: (a -> Bool) -> [a] -> Maybe a
Example 2: Return all the elements from list that satisfies
given predicate.
ListUtil.hs
getElements :: (a -> Bool) -> [a] -> [a] getElements predicateFun list = myFilter predicateFun list myFilter :: (a -> Bool) -> [a] -> [a] myFilter p [] = [] myFilter p (x:xs) | p x = x:myFilter p xs | otherwise = myFilter p xs
*Main> :load listUtil.hs [1 of 1] Compiling Main ( listUtil.hs, interpreted ) Ok, modules loaded: Main. *Main> *Main> getElements odd [2, 3, 5, 4, 6, 17, 19] [3,5,17,19] *Main> *Main> getElements even [2, 3, 5, 4, 6, 17, 19] [2,4,6] *Main> *Main> getElements even [] [] *Main>
Example 3: Get index of element that satisfies given predicate.
ListUtil.hs
getIndex :: (a -> Bool) -> [a] -> Maybe Int getIndex predicateFun list = myFilter predicateFun list 0 myFilter :: (a -> Bool) -> [a] -> Int -> Maybe Int myFilter _ [] _= Nothing myFilter p (x:xs) index | p x = Just index | otherwise = myFilter p xs (index+1)
Prelude> :load listUtil.hs [1 of 1] Compiling Main ( listUtil.hs, interpreted ) Ok, modules loaded: Main. *Main> *Main> getIndex odd [2, 3, 5, 4, 6, 17, 19] Just 1 *Main> getIndex even [2, 3, 5, 4, 6, 17, 19] Just 0 *Main> getIndex even [] Nothing *Main> *Main> :t getIndex getIndex :: (a -> Bool) -> [a] -> Maybe Int *Main>
Example 4: Get all indexes of elements in list that satisfies
given predicate.
ListUtil.hs
getIndexes :: (a -> Bool) -> [a] -> [Int] getIndexes predicateFun list = myFilter predicateFun list 0 myFilter :: (a -> Bool) -> [a] -> Int -> [Int] myFilter _ [] _= [] myFilter p (x:xs) index | p x = index : myFilter p xs (index+1) | otherwise = myFilter p xs (index+1)
*Main> :load listUtil.hs [1 of 1] Compiling Main ( listUtil.hs, interpreted ) Ok, modules loaded: Main. *Main> *Main> getIndexes odd [2, 3, 5, 4, 6, 17, 19] [1,2,5,6] *Main> getIndexes even [2, 3, 5, 4, 6, 17, 19] [0,3,4] *Main> getIndexes even [] []
No comments:
Post a Comment