Jam*_*ies 18 haskell scala lenses haskell-lens monocle-scala
假设我有一对转换函数
string2int :: String -> Maybe Int
int2string :: Int -> String
Run Code Online (Sandbox Code Playgroud)
我可以使用Optics轻松地代表这些.
stringIntPrism :: Prism String Int
但是,如果我想表示失败原因,我需要将它们作为两个单独的函数保留.
string2int :: String -> Validation [ParseError] Int
int2string :: Int -> String`
Run Code Online (Sandbox Code Playgroud)
对于这个简单的例子Maybe
非常好,因为我们总是可以假设失败是解析失败,因此我们实际上不必使用Either或Validation类型对此进行编码.
但是想象一下,除了解析Prism之外,我还想进行一些验证
isOver18 :: Int -> Validation [AgeError] Int
isUnder55 :: Int -> Validation [AgeError] Int
Run Code Online (Sandbox Code Playgroud)
将这些东西组合在一起是理想的,这样我就可以拥有
ageField = isUnder55 . isOver18 . string2Int :: ValidationPrism [e] String Int
这对于手工构建来说是相当微不足道的,但是它似乎是一个普遍的概念,在镜头/光学领域潜藏着可能存在的东西.是否存在处理此问题的现有抽象?
TL;博士
是否有一种标准的方法来实现部分镜头/棱镜/ iso,可以通过任意仿函数进行参数化,而不是直接绑定到Maybe?.
我上面使用了Haskell表示法,因为它更直接,但我实际上是在Scala中使用Monocle来实现它.但是,对于ekmett的Lens库特定的答案,我会非常满意.
我最近写了一篇关于索引光学的博客文章 ; 这也探讨了我们如何做硬核光学.
简而言之:Coindexed-optics是可能的,但我们还没有在那里做进一步的研究.特别是,因为如果我们尝试将这种方法转换lens
为镜头编码(从Profunctor到VL),它会变得更加毛茸茸(但我认为我们只能使用 7种类型变量).
如果不改变索引光学器件当前编码的方式,我们就无法做到这一点lens
.所以现在,您最好使用验证特定的库.
给出一些困难的暗示:当我们试图用Traversal
s 组成时,我们应该有
-- like `over` but also return an errors for elements not matched
validatedOver :: CoindexedOptic' s a -> (a -> a) -> s -> (ValidationErrors, s)
Run Code Online (Sandbox Code Playgroud)
或者是其他东西?如果我们只能组成Coindexed Prisms,它们的价值就不能证明它们的复杂性; 它们不会"适应"光学框架.
归档时间: |
|
查看次数: |
603 次 |
最近记录: |