使用Lens过滤复合结构

10

我有一个 [(a, Maybe b)],想要得到一个 [(a, b)],其中过滤掉所有第二个元素是Nothing的对。 是否有一种简洁的方式使用 lens 描述这个操作?

3个回答

13

你觉得这个怎么样?

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

使用(^..)folded来自Control.Lens.Fold,以及aside_Just来自Control.Lens.Prism

关键在于aside,这是一个方便的函数,它可以从作用于元组组成部分的棱镜构建一个作用于整个元组的棱镜。


12

尽管这些镜头非常巧妙,但以下内容可能是简洁的标志:

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

(更不用说可读性了。)


2
暂且不谈我完全忘记了 Haskell 有列表推导这一事实...为什么它也会过滤呢?我习惯于像那些告诉我存在非穷尽模式的东西。难道列表推导只是简单地丢弃代数类型中不匹配的构造值吗?我从未听说过这个特性。 - Narvius
4
这句话的意思是:根据 Haskell 2010 报告第22页的说法,这样的列表推导式返回一个列表,该列表由在限定符列表中嵌套深度优先评估生成器所创建的连续环境中评估e所产生的元素组成。变量的绑定按照正常的模式匹配规则进行(参见第3.17节),如果匹配失败,则跳过列表的那个元素 - Ingo
4
当使用 <- 进行模式匹配失败时,会调用相应 monad 的 fail 函数,对于列表来说,这个函数是 [] - sdcvvc
@sdcwc 啊,好老的 Haskell。你永远不会离下一个强大的泛化太远。 - Narvius

4
mapMaybe sequenceA :: [(a, Maybe b)] -> [(a,b)]

你需要导入 Data.TraversableData.Maybe 并拥有一个 Traversable ((,) a) 实例。我让读者自己想一想这是如何工作的。

那是一个有趣的答案。 - rob

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接