Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
201 views
in Technique[技术] by (71.8m points)

Same LHS, different RHS in Haskell

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:

  • filterF receives 2 arguments: funct (a function that takes an argument of type a and returns a Bool) and u (a foldable monoid)
  • We let funct decide, for every element in u, if it should stay or not. If it does stay, we "raise" it up to the "rank" of an Applicative with pure
  • 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.

question from:https://stackoverflow.com/questions/65952082/same-lhs-different-rhs-in-haskell

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Let's write f for (x -> if funct x then pure x else mempty), when funct is Data.Char.isUpper.

We can evaluate filterF Data.Char.isUpper "aNA aRe mEre" as follows:

filterF Data.Char.isUpper "aNA aRe mEre"
= -- definition of filterF
folMap f "aNA aRe mEre"
= -- definition of foldMap
f 'a' <> f 'N' <> f 'A' <> f ' ' <> f 'a' <> f 'R' <> ....
= -- definition of f
mempty <> pure 'N' <> pure 'A' <> mempty <> mempty <> pure 'R' <> ...
= -- monoidal laws
pure 'N' <> pure 'A' <> pure 'R' <> pure 'E'

From here, using the definition of <> from the several monoids you mentioned, you should be able to conclude.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...