[kepler-dev] Re: filtering from a list

Bertram Ludaescher ludaesch at sdsc.edu
Fri Jul 16 07:43:15 PDT 2004


I forgot to mention: The crux of the declarative solution is the
'foldl' higher-order function.  Don't have a good reference right now,
but try 'google foldl foldr'.

For the procedural solution, we'll need sth else I think.

Bertram

PS This is has to do with the Kepler/SPA PIW workflow..


>>>>> "BL" == Bertram Ludaescher <ludaesch at sdsc.edu> writes:
BL> 
BL> Xiaowen:
BL> 
BL> Regarding your question yesterday, i.e., how to take the first N
BL> elements from a list that pass a certain filter, here is a preliminary
BL> solution in Haskell. Note that it has the inefficiency that it
BL> first filters the whole list, then takes N elements of the result.
BL> 
BL> I can only think declaratively at this hour ... my procedural brain
BL> needs another hour to wake up (but then I'll be at the SPA meeting
BL> already ;-)
BL> 
BL> Here is the program:
BL> 
BL>     -- Some sample integer list
BL>     my_list = [1..30] 
BL> 
BL>     -- Test whether an integer x is even
BL>     my_test x = even x
BL> 
BL>     -- Given a predicate 'test' and a list (queue) 'ys',
BL>     -- .. add a given 'x' to 'ys', if 'test(x)' is true
BL>     add_if test ys x  = if (test x) 
BL>                         then ys++[x]
BL>                         else ys
BL> 
BL>     -- Given a 'test' and a 'list' return the filtered 'list',
BL>     -- ... i.e., containing only elements passing the 'test' 
BL>     my_filter :: (a -> Bool) -> [a] -> [a]
BL>     my_filter test list = (foldl (add_if test) [] list)
BL> 
BL>     -- Now apply my_filter on my_list using my_test
BL>     go = my_filter my_test my_list
BL> 
BL>     -- Take only the first N elements: 
BL>     goN n = (take n go)
BL> 
BL> 
BL> Here is the trace:
BL> 
BL> 
BL>     Hugs session for:
BL>     c:\Program Files\Hugs98\lib\Prelude.hs
BL>     c:\my\Haskell\kepler.hs
BL> 
BL> Infer the type of 'my_test'
>> :t my_test
BL>     my_test ::  a -> Bool
BL> (it's a test on an element of type (a)lpha returning a Boolean
BL> 
BL> What's the type of add_if?
>> :t add_if
BL>     add_if :: (a -> Bool) -> [a] -> a -> [a]
BL> 
BL> What's the type of my_filter?
>> :t my_filter
BL>     my_filter :: (a -> Bool) -> [a] -> [a]
BL> 
BL> Now do the filter operation:
>> go
BL>     [2,4,6,8,10,12,14,16,18,20,22,24,26,28,30] :: [Integer]
BL> 
BL> What's the type of goN
>> :t goN
BL>     goN :: Int -> [Integer]
BL> (it takes a number (the count of elements to return) and returns a
BL> list of results)
BL> 
BL> So here, finally, how to pick the first 3:
>> goN 3
BL>     [2,4,6] :: [Integer]
BL> 
BL> 
BL> Again, this still has the disadvantage of filtering even after the
BL> first N elements are found...
BL> 
BL> More later...
BL> 
BL> Bertram



More information about the Kepler-dev mailing list