Filtering composite structures with Lens
Asked Answered
W

3

10

I have a [(a, Maybe b)], and want to obtain a [(a, b)], with all pairs where the second element was Nothing filtered out. Is there a concise way to describe this operation using lens?

Winchester answered 25/10, 2013 at 14:7 Comment(0)
H
13

How about something like

[('a',Just 1),('b',Nothing)]^..folded.aside _Just 

Using (^..) and folded from Control.Lens.Fold and aside and _Just from Control.Lens.Prism.

The key is aside, a handy function that builds a prism working on a pair from a prism working on a component of the pair.

Hindgut answered 25/10, 2013 at 14:22 Comment(0)
M
12

Notwithstanding the ingeniousity of the Lenses, the follwoing would probably be the mark for conciseness:

[ (a, b) | (a, Just b) <- list ]

(Not to speak of readability.)

Molton answered 25/10, 2013 at 15:1 Comment(4)
Setting aside for a moment the fact that I totally forgot Haskell had list comprehensions... Why exactly does this also filter? I'm used to things like those telling me there's a non-exhaustive pattern. Do list comprehensions simply throw away values with non-matching constructors for algebraic types? I've never heard of that feature.Winchester
Exactly that, @Narvius. Haskell 2010 report, pg. 22: Such a list comprehension returns the list of elements produced by evaluating e in the successive environments created by the nested, depth-first evaluation of the generators in the qualifier list. Binding of variables occurs according to the normal pattern matching rules (see Section 3.17), and if a match fails then that element of the list is simply skipped over.Molton
When pattern matching with <- fails, it calls fail of the corresponding monad, and for lists this is [].Mirtamirth
@sdcwc Ah, good ol' Haskell. You're never far from the next powerful generalization.Winchester
M
4
mapMaybe sequenceA :: [(a, Maybe b)] -> [(a,b)]

You need to import Data.Traversable, Data.Maybe and have a Traversable ((,) a) instance. I leave figuring how does this work to the reader.

Mirtamirth answered 25/10, 2013 at 16:1 Comment(1)
That's a fun answer.Inserted

© 2022 - 2024 — McMap. All rights reserved.