[kepler-dev] filtering from a list

Bertram Ludaescher ludaesch at sdsc.edu
Fri Jul 16 07:33:27 PDT 2004


Xiaowen:

Regarding your question yesterday, i.e., how to take the first N
elements from a list that pass a certain filter, here is a preliminary
solution in Haskell. Note that it has the inefficiency that it
first filters the whole list, then takes N elements of the result.

I can only think declaratively at this hour ... my procedural brain
needs another hour to wake up (but then I'll be at the SPA meeting
already ;-)

Here is the program:

    -- Some sample integer list
    my_list = [1..30] 

    -- Test whether an integer x is even
    my_test x = even x

    -- Given a predicate 'test' and a list (queue) 'ys',
    -- .. add a given 'x' to 'ys', if 'test(x)' is true
    add_if test ys x  = if (test x) 
                        then ys++[x]
                        else ys

    -- Given a 'test' and a 'list' return the filtered 'list',
    -- ... i.e., containing only elements passing the 'test' 
    my_filter :: (a -> Bool) -> [a] -> [a]
    my_filter test list = (foldl (add_if test) [] list)

    -- Now apply my_filter on my_list using my_test
    go = my_filter my_test my_list

    -- Take only the first N elements: 
    goN n = (take n go)


Here is the trace:


    Hugs session for:
    c:\Program Files\Hugs98\lib\Prelude.hs
    c:\my\Haskell\kepler.hs

Infer the type of 'my_test'
    > :t my_test
    my_test ::  a -> Bool
(it's a test on an element of type (a)lpha returning a Boolean

What's the type of add_if?
    > :t add_if
    add_if :: (a -> Bool) -> [a] -> a -> [a]

What's the type of my_filter?
    > :t my_filter
    my_filter :: (a -> Bool) -> [a] -> [a]

Now do the filter operation:
    > go
    [2,4,6,8,10,12,14,16,18,20,22,24,26,28,30] :: [Integer]

What's the type of goN
    > :t goN
    goN :: Int -> [Integer]
(it takes a number (the count of elements to return) and returns a
list of results)

So here, finally, how to pick the first 3:
    > goN 3
    [2,4,6] :: [Integer]


Again, this still has the disadvantage of filtering even after the
first N elements are found...

More later...

Bertram



More information about the Kepler-dev mailing list