`eitherPrism`实现简化咨询:基于optics-core的Prism'
eitherPrism实现的简化分析
这里的Prism'来自optics-core库而非lens。
你的eitherPrism实现已经相当简洁,核心逻辑没有冗余,但可以做一些语法层面的简化,让代码更贴合函数式风格:
简化后的实现
{- | Given two @Prism'@'s whose filepaths are distinct (ie., both @a@ and @b@ encode to distinct filepaths), return a new @Prism'@ that combines both. If this distinctness property does not hold between the input @Prism'@'s, then the resulting @Prism'@ will not be lawful. -} eitherPrism :: Prism' FilePath a -> Prism' FilePath b -> Prism' FilePath (Either a b) eitherPrism p1 p2 = prism' (bimap (review p1) (review p2)) (\fp -> Left <$> preview p1 fp <|> Right <$> preview p2 fp)
简化点说明
- review部分:用
bimap (review p1) (review p2)替代原有的either (review p1) (review p2),两者逻辑完全等价——都是对Either的两个分支分别应用对应的review操作,但bimap是更贴合Either类型的函数式写法。 - preview部分:用
<|>替代asum,因为asum对Maybe列表的行为就是依次尝试每个Maybe值、取第一个Just结果,这和Maybe类型的<|>操作语义完全一致,写法更简洁。
关于“最简形式”
这个简化后的版本已经是逻辑层面的最简形式了。因为eitherPrism的核心需求就是:
- 对
Either a b的两个分支分别用对应Prism生成文件路径; - 对输入文件路径尝试匹配两个Prism,返回第一个匹配的分支结果。
这两点都无法再进一步压缩,除非依赖optics-core中更高阶的组合子,但那样反而会降低代码可读性,不如当前的实现直观。
另外需要注意:原注释中提到的“两个Prism对应的文件路径必须互不重叠”的合法性要求,在简化版本中依然存在——如果存在某个文件路径同时匹配两个输入Prism,组合后的Prism会违反Prism的合法性规则(review . preview无法保证等于恒等操作)。
内容的提问来源于stack exchange,提问作者Sridhar Ratnakumar
相关产品推荐
相关产品推荐

