20

假设我有一对转换函数

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 库的答案感到非常满意。

4

1 回答 1

6

我最近写了一篇关于索引光学的博客文章;这也探讨了我们如何做共索引光学。

简而言之:共索引光学是可能的,但我们还没有在那里做一些进一步的研究。特别是,因为如果我们尝试将这种方法转化lens为镜头编码(从 Profunctor 到 VL),它会变得更加棘手(但我认为我们只能使用7 个类型变量)。

如果改变索引光学器件当前在lens. 所以现在,你最好使用验证特定的库。

提示困难:当我们尝试用Traversals 作曲时,我们应该有

-- like `over` but also return an errors for elements not matched
validatedOver :: CoindexedOptic' s a -> (a -> a) -> s -> (ValidationErrors, s)

或者是其他东西?如果我们只能组成 Coindexed Prism,那么它们的价值将无法证明它们的复杂性;它们不会“适合”光学框架。

于 2017-04-29T20:51:36.493 回答