The exercise I need to solve is this:
Write a filter function for Foldable types using foldMap.
filterF
:: ( Applicative f
, Foldable t
, Monoid (f a)
)
=> (a->Bool) -> t a -> f a
filterF=undefined
The function should return True for all of the following tests:
unit_testFilterF1 = filterF Data.Char.isUpper "aNA aRe mEre" == "NARE"
unit_testFilterF1 = filterF Data.Char.isUpper "aNA aRe mEre" == First (Just 'N')
unit_testFilterF1 = filterF Data.Char.isUpper "aNA aRe mEre" == Min 'A'
unit_testFilterF1 = filterF Data.Char.isUpper "aNA aRe mEre" == Max 'R'
unit_testFilterF1 = filterF Data.Char.isUpper "aNA aRe mEre" == Last (Just 'E')
Using the hints our teacher gave us, I wrote this solution:
filterF
:: ( Applicative f
, Foldable t
, Monoid (f a)
)
=> (a-> Bool) -> t a -> f a
filterF funct u= foldMap (\x -> if funct x then pure x else mempty) u
Mind you, I obviously don't understand this solution fully, as I can't figure out why those tests return True. What I do understand is this:
filterFreceives 2 arguments:funct(a function that takes an argument of typeaand returns a Bool) andu(a foldable monoid)- We let
functdecide, for every element inu, if it should stay or not. If it does stay, we "raise" it up to the "rank" of anApplicativewithpure - we then combine all of the elements into one using the operation defined by the monoidal state of
f
Given that in the tests we have the same LHS and different RHS, I would guess that the RHS influences the structure of f. A bit like how we would do in:
unit_testFilterF6=filterF Data.Char.isUpper"aNA aRe mEre" :: First Char
Can someone explain further what's going on here? I am a Haskell beginner.