I'm trying to write a function that takes a predicate f and a list and returns a list consisting of all items that satisfy f with preserved order. The trick is to do this using only higher order functions (HoF), no recursion, no comprehensions, and of course no filter.
+4
A:
I think you can use map
this way:
filter' :: (a -> Bool) -> [a] -> [a]
filter' p xs = concat (map (\x -> if (p x) then [x] else []) xs)
You see? Convert the list in a list of lists, where if the element you want doesn't pass p, it turns to an empty list
filter' (> 1) [1 , 2, 3 ]
would be: concat [ [], [2], [3]] = [2,3]
In prelude there is concatMap
that makes the code simplier :P
the code should look like:
filter' :: (a -> Bool) -> [a] -> [a]
filter' p xs = concatMap (\x -> if (p x) then [x] else []) xs
using foldr, as suggested by sclv, can be done with something like this:
filter'' :: (a -> Bool) -> [a] -> [a]
filter'' p xs = foldr (\x y -> if p x then (x:y) else y) [] xs
Marco
2010-09-03 04:24:15
There are other ways of doing it, Im kinda noob with haskell :P
Marco
2010-09-03 04:29:29
+1
A:
Well, are ifs and empty list allowed?
filter = (\f -> (>>= (\x -> if (f x) then return x else [])))
kohomologie
2010-09-03 04:55:02
This is exactly as my answer only that it uses list monad..Or is there any other difference?Also, it is very unclear and hard to read..
Marco
2010-09-03 05:05:45
Well, if you change [] with mzero and import Control.Monad, you'll get a filter working in any monad, not just in List. It is not filterM, however.
kohomologie
2010-09-03 05:24:48