Scala 带误差处理的透镜/棱镜
假设我有一对转换函数Scala 带误差处理的透镜/棱镜,scala,haskell,haskell-lens,lenses,monocle-scala,Scala,Haskell,Haskell Lens,Lenses,Monocle Scala,假设我有一对转换函数 string2int :: String -> Maybe Int int2string :: Int -> String 我可以用光学很容易地表示这些 stringIntPrism::Prism String Int 然而,如果我想表示失败原因,我需要将它们作为两个单独的函数 string2int :: String -> Validation [ParseError] Int int2string :: Int -> String` 对于这个
string2int :: String -> Maybe Int
int2string :: Int -> String
我可以用光学很容易地表示这些
stringIntPrism::Prism String Int
然而,如果我想表示失败原因,我需要将它们作为两个单独的函数
string2int :: String -> Validation [ParseError] Int
int2string :: Int -> String`
对于这个简单的例子,也许
是非常好的,因为我们总是可以假设一个失败是一个解析失败,因此我们实际上不必使用非此即彼或验证类型来编码它
然而,想象一下,除了解析棱镜之外,我还想执行一些验证
isOver18 :: Int -> Validation [AgeError] Int
isUnder55 :: Int -> Validation [AgeError] Int
如果能把这些东西组合在一起,这样我就可以
ageField=低于55。18岁以上。string2Int::ValidationPrism[e]字符串Int
这是相当琐碎的手工制作,但它似乎是一个足够普遍的概念,在镜头/光学领域可能已经有了一些潜在的东西。是否存在处理此问题的现有抽象
tl;博士
是否有一种标准的方法来实现部分透镜/棱镜/iso,它可以在任意函子上参数化,而不是直接绑定到Maybe
我在上面使用了Haskell符号,因为它更直接,但实际上我使用Scala中的Monocle来实现这一点。然而,我非常乐意得到一个关于ekmett透镜库的具体答案。我最近写了一篇关于索引光学的文章;这也探索了一点我们如何制作共索引光学
简言之:共指数光学是可能的,但我们还没有做一些进一步的研究。特别是,如果我们尝试将这种方法转换为透镜的编码(从Profunctor到VL),它会变得更加复杂(但我认为我们可以只使用7个类型变量)
如果不改变索引光学元件当前在镜头中的编码方式,我们就无法真正做到这一点。所以现在,您最好使用特定于验证的库
提示一下困难:当我们尝试使用Traversal
s进行创作时,我们应该
-- like `over` but also return an errors for elements not matched
validatedOver :: CoindexedOptic' s a -> (a -> a) -> s -> (ValidationErrors, s)
还是别的什么?如果我们只能够组合出共索引棱镜,它们的价值将无法证明它们的复杂性;它们无法“适应”光学框架。我记得很久以前reddit讨论过一个类似的问题。在这本书中,爱德华·科米特(Edward Kmett)介绍了一种“共索引棱镜”(coindexed prisms),它能够报告错误信息,同时保持与普通透镜的组合。显然,由于类型推断问题,它们很难适应lens框架,因此它们没有实现。我认为遍历的概念在这里是合适的。