我一直在读A wreq tutorial:

镜头提供了一种聚焦于Haskell值一部分的方法。对于
例如,Response类型具有responseStatus镜头,
着重于服务器返回的状态信息。

ghci> r ^. responseStatus
Status {statusCode = 200, statusMessage = "OK"}

^.运算符将值作为第一个参数,将镜头作为其参数
第二,并返回镜头聚焦的部分值。

我们使用功能组合来构成镜头,这使我们能够
轻松关注深层嵌套结构的一部分。
ghci> r ^. responseStatus . statusCode
200

我想不出一种方法,用此顺序的参数完成函数组合可以按该顺序处理嵌套结构。

外观:r ^. responseStatus . statusCode可以是r ^. (responseStatus . statusCode)(r ^. responseStatus) . statusCode

在第一个语句中,我们构造了一个函数,首先处理statusCode(从记录Status?中获取它-我可以从显示的值Status {statusCode = 200, statusMessage = "OK"}推导出来),然后将其传递给responseStatus,该必须处理响应状态。因此,反之亦然:实际上,状态代码是响应状态的一部分。

二读对我来说也没有意义,因为它也首先处理状态码。

最佳答案

正确阅读r ^. responseStatus . statusCoder ^. (responseStatus . statusCode)。这是很自然的,因为函数组合在应用于两个参数时会返回一个函数,因此(r ^. responseStatus) . statusCode必须返回一个函数,而不是可以打印出的任何值。

这仍然悬而未决,为什么镜片会以“错误”的顺序组成。由于镜头的实现有些不可思议,因此让我们来看一个简单的示例。
first是一个映射成对的第一个元素的函数:

first :: (a -> b) -> (a, c) -> (b, c)
first f (a, b) = (f a, b)
map . first是做什么的? first接受作用在第一个元素上的函数,并返回作用在对上的函数,如果我们用这种方式将类型括起来,则更明显:
first :: (a -> b) -> ((a, c) -> (b, c))

另外,还记得map的类型:
map :: (a -> b) -> ([a] -> [b])
map接受作用于元素的函数,并返回作用于列表的函数。现在,f . g可以通过首先应用g然后将结果提供给f来工作。因此,map . first接受作用于某种元素类型的函数,将其转换为作用于对的函数,然后将其转化为作用于对的列表的函数。
(map . first) :: (a -> b) -> [(a, c)] -> [(b, c)]
firstmap都将作用在结构的一部分上的函数转换为作用在整个结构上的函数。在map . first中,first的整个结构是map的重点。
(map . first) (+10) [(0, 2), (3, 4)] == [(10, 2), (13, 4)]

现在看一下镜头的类型:
type Lens = forall f. Functor f => (a -> f b) -> (s -> f t)

现在尝试忽略Functor位。如果我们斜视一下,这类似于mapfirst的类型。碰巧的是,镜头还将作用在结构部分上的功能转换为作用在整个结构上的功能。在上面的签名中,s表示整个结构,而a表示其一部分。由于我们的输入函数可以将a的类型更改为b(如a -> f b所示),因此我们还需要t参数,该参数的大致含义是“在将s更改为a之后,b的类型”。
statusCode是一个将作用于Int的函数转换为作用于Status的函数的镜头:
statusCode :: Functor f => (Int -> f Int) -> (Status -> f Status)
responseStatus将作用于Status的函数转换为作用于Response的函数:
responseStatus :: Functor f => (Status -> f Status) -> (Response -> f Response)
responseStatus . statusCode的类型遵循与map . first相同的模式:
responseStatus . statusCode :: Functor f => (Int -> f Int) -> (Response -> f Response)
^.到底如何工作还有待观察。它与镜头的核心机制和魔力息息相关。我不会在这里重申它,因为有很多关于它的著作。作为介绍,我建议您查看this onethis one,您也可以观看this excellent video.

07-28 09:44