使用 Maybe 遍历嵌套记录的更短方法

Shorter way to traverse nested record with Maybe

是否有 shorter/cleaner 编写以下代码片段的方法:

fromMaybe "" $ fmap (^. fullName) (bi ^. bookerContact)

这里bi ^. bookerContact可能会产生Maybe Contact条记录,这就是^. fullName需要fmapped的原因。在嵌套遍历之后,如果我们以 Nothing 结尾,我们使用 fromMaybe "" 将其默认为空字符串。

一种简单的整理方法是使用 maybe 而不是 fromMaybe/fmap 组合:

maybe "" (^. fullName) (bi ^. bookerContact)

您还可以引入 _Just 棱镜,将所有钻孔表达为单个光学元件:

fromMaybe "" (bi ^? bookerContact . _Just . fullName)

请注意,我们已从 (^.) 切换到 (^?)。这反映了将 _Just 添加到链中如何将以前的透镜(并恰好到达一个目标)变成遍历(可能无法到达任何目标)。


也可以利用 Text 是幺半群的优势,并使用 Data.Foldable 中的 fold...

fold (bi ^? bookerContact . _Just . fullName)

... 或 foldOf,如果您更喜欢 lens 拼写:

foldOf (bookerContact . _Just . fullName) bi

As the docs point out, foldOf is equivalent to (^.) (which is essentially view specialised to (->)), 所以这也可以通过折叠 Maybe Text:

bi ^. bookerContact . _Just . fullName