假设我有一对转换函数
string2int :: String -> Maybe Int
int2string :: Int -> String
使用Optics,我可以很容易地表示这些。
stringIntPrism :: Prism String Int
然而,如果我想要表示失败原因,我需要将它们保留为两个单独的函数。
string2int :: String -> Validation [ParseError] Int
int2string :: Int -> String`
对于这个简单的例子,Maybe
是完全可以的,因为我们总是可以假定失败是一个解析失败,因此我们实际上不必使用 Either 或 Validation 类型来编码它。
然而,想象一下,在我的解析 Prism 之外,我还想执行一些验证。
isOver18 :: Int -> Validation [AgeError] Int
isUnder55 :: Int -> Validation [AgeError] Int
希望能够将这些东西组合在一起,比如我可以这样做:
ageField = isUnder55 . isOver18 . string2Int :: ValidationPrism [e] String Int
手动构建这个函数很容易,但似乎这是一个常见的概念,也许在Lenses / Optics领域中已经存在处理这个问题的抽象。是否存在处理这个问题的现有抽象?
总之:
是否有标准方法实现可以针对任意Functor参数化部分镜头/棱镜/等距变换,而不是直接绑定在Maybe上?
我在上面使用了Haskell符号,因为它更简单明了,但实际上我正在使用Scala中的Monocle来实现这个。然而,如果回答针对例如ekmett的Lens库是非常具体的,我也会非常高兴。