你如何构图_Just with the at lens

How do you compose _Just with the at lens

我不知道如何使用镜头访问记录来很好地访问 Data.Map。说我有:

{-# LANGUAGE TemplateHaskell #-}

import Control.Lens
import Control.Lens.TH
import Data.Map

data Person =
  Person
    { _age :: Int
    , _name :: String
    }
  deriving (Show)

makeLenses ''Person

database = fromList [(1, Person 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

问题是无法保证 database table 将包含请求的值,因此这两个表达式都是 Traversal' (Map Int Person) Int 类型。所以在这种情况下 johnsAge :: Maybe Int.

如果您使用 ^. 访问遍历并且最终值(在本例中 age)是一个 Monoid,那么您将获得零值,并且如果有多个命中(不可能对于 Map) 然后你得到它们的连接。但是在这种情况下它不是幺半群,所以你会得到一个类型错误。