如何使用镜头在嵌套地图中设置值

用户1747134

我有以下程序:

{-# LANGUAGE TemplateHaskell #-}
import qualified Data.Map.Strict as Map
import Control.Lens

data MyLabel = MyLabel { _label :: String } deriving (Show, Eq, Ord)
data MyMap = MyMap { _vals :: Map.Map String MyLabel } deriving (Show, Eq, Ord)
makeLenses ''MyLabel
makeLenses ''MyMap

sample :: MyMap
sample = MyMap { _vals = Map.fromList [("foo", MyLabel "bar")] }

现在,我想知道如何f使用镜头进行转换,例如:

f sample "quux" == MyMap { _vals = Map.fromList [("foo", MyLabel "quux")] }

我了解到at应该使用Lens库中的函数来修改Maps,因此我正在尝试执行以下操作:

sample ^. vals & at "foo" . label .~ Just "quux"

但这会产生一条错误消息,这对我来说不是很容易理解。什么是正确的方法?

hao

尝试以下尺寸:

{-# LANGUAGE TemplateHaskell #-}

module Main where

import qualified Data.Map.Strict as Map
import Control.Lens

data MyLabel =
  MyLabel { _label :: String } deriving (Show, Eq, Ord)

data MyMap =
  MyMap { _vals :: Map.Map String MyLabel } deriving (Show, Eq, Ord)

makeLenses ''MyLabel
makeLenses ''MyMap

sample :: MyMap
sample =
  MyMap (Map.fromList [("foo", MyLabel "bar")])

main :: IO ()
main =
  print (sample & (vals . at "foo" . _Just . label .~ "quux"))

请记住,在设置时,您尝试构建type函数MyMap -> MyMap您可以通过将一堆光学元件链接在一起(vals . at "foo" . _Just . label),然后选择设置器操作(.~)来实现。您不能像^.使用setter操作那样混合和匹配getter操作.~因此,每个二传手或多或少都是这样的:

foo' = (optic1 . optic2 . optic3 . optic4) .~ value $ foo
--     _________this has type Foo -> Foo___________

为了提高可读性,我们使用&的翻转版本$

foo' = foo & (optic1 . optic2 . optic3 . optic4) .~ value

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章