Haskell 用at镜头怎么作曲

Haskell 用at镜头怎么作曲,haskell,haskell-lens,Haskell,Haskell Lens,我不知道如何通过镜头访问记录来很好地组合对Data.Map的访问。说我有: {-#语言模板haskell} 进口管制.镜头 进口管制.Lens.TH 导入数据。映射 数据员= 人 {u年龄::Int ,_name::String } 派生(显示) 制造透镜的人 数据库=fromList[(1,35人“John”)] 哪一条线能让你知道约翰的年龄?因为 johsnAge = database ^. at 1 . _Just . age 给我的是错误: • No instance for

我不知道如何通过镜头访问记录来很好地组合对
Data.Map
的访问。说我有:

{-#语言模板haskell}
进口管制.镜头
进口管制.Lens.TH
导入数据。映射
数据员=
人
{u年龄::Int
,_name::String
}
派生(显示)
制造透镜的人
数据库=fromList[(1,35人“John”)]
哪一条线能让你知道约翰的年龄?因为

johsnAge = database ^. at 1 . _Just . age
给我的是错误:

    • No instance for (Monoid Int) arising from a use of ‘_Just’
    • In the first argument of ‘(.)’, namely ‘_Just’
      In the second argument of ‘(.)’, namely ‘_Just . age’
      In the second argument of ‘(^.)’, namely ‘at 1 . _Just . age’
   |
18 | johsnAge = database ^. at 1 . _Just . age
   |  

你能用
^?
ix
代替吗

*Q65578938> database ^? ix 1 . age
Just 35
*Q65578938> database ^? ix 2 . age
Nothing

您需要这样做:

johsnAge = database ^? at 1 . _Just . age
或者为了更简洁

johnsAge = database ^? ix 1 . age
问题是不能保证
数据库
表将包含请求的值,因此这两个表达式的类型都是
Traversal'(Map Int Person)Int
。所以在本例中,
johnsAge::可能是Int

如果您使用
^.
访问遍历,并且最终值(在本例中
age
)是一个幺半群,那么您将获得零值,如果存在多个命中(对于
映射
不可能),那么您将获得它们的串联。然而,在这种情况下,它不是一个幺半群,因此您会得到一个类型错误