grep in Perl - filter in Haskell
By using the the grep
function in Perl, one can pick elements from a list that match a certain condition. Haskell uses the filter
function to do the same work.
Perl Example
One way to use grep
in Perl is:
my @people = qw/Kim Jim Jane Blane Tim/; my $predicate = sub { shift =~ m/im$/ }; my @filtered_people = grep $predicate->($_), @people;
- Define a list of people
- Create a predicate1, as a code reference
- apply grep to the predicate and people list
A predicate expression is applied to each person in the list. The filtered list is all the elements that cause the expression to evaluate to true. Here the predicate returns true when a name ends with 'im'.
It's common in Perl to use a block instead of an expression with grep
. This allows one to inline the test:
my @filtered_people = grep { m/im$/ } @people
Haskell Example
In Haskell one can use filter
like so:
import Data.List (isSuffixOf) people = ["Kay", "Jed", "Ned", "Jay", "Ray"] predicate :: String -> Bool predicate xs = "ay" `isSuffixOf` xs filteredPeople = filter predicate people
- import
isSuffixOf
function from the Data.List module - Define a list of people
- Define the type signature of the predicate
- Define the value constructor for the predicate
- apply
filter
to a predicate and the list of people
We could combine the last three lines into one using a lambda function:
filteredPeople = filter (\xs -> "ay" `isSuffixOf` xs) people
Lambda functions are similar to anonymous subroutines in Perl.
1 The function that determines if a condition is met is commonly called a predicate.
There's a key difference between Haskell's
filter
function and Perl'sgrep
: the former is lazy.This means that you can filter an infinite list (e.g. the list of all non-negative integers
[0..]
) and get the results back in non-infinite time.