假设我有一对转换函数
string2int :: String -> Maybe Int
int2string :: Int -> String
我可以使用光学很容易地表示这些。
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
这对于手工构建来说相当简单,但它似乎是一个足够普遍的概念,在镜头/光学领域可能已经潜伏着一些东西可以做到这一点。是否存在处理此问题的现有抽象?
tl;博士
是否有实现部分镜头/棱镜/iso的标准方法,可以通过任意函子进行参数化,而不是直接绑定到Maybe?
我在上面使用了 Haskell 表示法,因为它更直接,但是我实际上是在 Scala 中使用 Monocle 来实现它。但是,我会对特定于 ie ekmett 的 Lens 库的答案感到非常满意。