Haskell 使用镜头s t a b获得价值
我想写一个函数,在镜头的帮助下将函数(a->b)转换成函数(s->t)(编辑:我意识到这个函数已经存在于Haskell 使用镜头s t a b获得价值,haskell,haskell-lens,lenses,Haskell,Haskell Lens,Lenses,我想写一个函数,在镜头的帮助下将函数(a->b)转换成函数(s->t)(编辑:我意识到这个函数已经存在于Setter t a b中,被称为over或%~,但它没有回答下面使用镜头获取值的问题)。这看起来很简单,但我得到了一个令人困惑的类型错误。为了生成一个更为简单的例子,考虑下面的函数,它简单地返回由透镜从第二个参数中提取的值: f :: Lens s t a b -> s -> a f l s = s ^. l 这不能编译。有两个错误,都在^的第二个参数中。(即l): 无法将类
Setter t a b
中,被称为over
或%~
,但它没有回答下面使用镜头获取值的问题)。这看起来很简单,但我得到了一个令人困惑的类型错误。为了生成一个更为简单的例子,考虑下面的函数,它简单地返回由透镜从第二个参数中提取的值:
f :: Lens s t a b -> s -> a
f l s = s ^. l
这不能编译。有两个错误,都在^的第二个参数中。(即l):
- 无法将类型“t”与“s”匹配
- 无法将类型“a”与“b”匹配
f :: Getter s a -> s -> a
f l s = s ^. l
然后,我意识到在中,Lens和Getter之间的箭头指定s=t,a=b。是否无法使用常规
镜头s t a b
从s
类型的值中获取a
类型的值?使用^的问题不在于此,而在于其类型签名。如果我们取消它的定义,我们可以将它用于f
:
f :: Lens s t a b -> s -> a
f l s = getConst $ l Const s
如果您将Lens
:的定义扩展到all(f::*->*),这一点最容易理解。函子f=>(a->fb)->s->ft
有一种方法
f :: Lens s t a b -> s -> a
f l s = getConst (l Const s)
这也正是(^.)的定义。我不知道为什么(^.)的类型被这样限制,可能只是为了简单。为什么不直接使用Lens s a
或简单地使用Simple Lens s s a
?因为我需要更改容器和值的类型。我怀疑更通用的签名会使类型推断更加困难,因此需要一些^不需要的丑陋签名。
。