使用 Lens 获得价值 s a b

Getting value with a Lens s t a b

我想写一个函数,借助 Lens s t a b (编辑:我意识到这个函数已经存在 Setter s t a b 并被称为 over%~,但它没有回答下面使用镜头获取值的问题)。看起来很简单,但我遇到了一个令人困惑的类型错误。举一个更小的例子,考虑下面的函数,它只是 returns 镜头从第二个参数中提取的值:

f :: Lens s t a b -> s -> a
f l s = s ^. l

这无法编译。有 2 个错误,都在 ^ 的第二个参数中。 (即 l):

但是,以下编译:

f :: Getter s a -> s -> a
f l s = s ^. l

然后,我意识到在hierarchy of lens types中,Lens和Getter之间的箭头指定了s=t,a=b。有没有办法使用通用的 Lens s t a bs 类型的值中获取 a 类型的值?

使用 ^. 的问题不是 its implementation,而是它的类型签名。如果我们解除它的定义,我们可以将它用于 f:

f :: Lens s t a b -> s -> a 
f l s = getConst $ l Const s

如果扩展 Lens 的定义,这将最容易理解:forall (f :: * -> *). Functor f => (a -> f b) -> s -> f t.

有办法。

f :: Lens s t a b -> s -> a
f l s = getConst (l Const s)

这也正是(^.)的定义。我不确定为什么 (^.) 的类型以这种方式受到限制,可能只是为了简单起见。