我一直在尝试使用镜头和容器并取得了一些成功,但我在尝试使用 Data.Map 的过滤遍历时遇到了我的理解限制 - 我可以更改地图中的单个实例或遍历所有实例,但我不能弄清楚如何对一些可识别的分区(即范围内的键)进行操作。
本质上,我正在尝试对地图做一些类似于 Gabriel Gonzalez 优秀镜头教程对列表所做的事情 [1]
这是我的代码的工作框架,traverseSome
其中我不知道如何编写注释掉的函数。任何帮助都感激不尽!
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE RankNTypes #-}
import Control.Lens
import Control.Monad.State
import qualified Data.Map.Strict as Map
import qualified Data.Set as Set
type CharSet = Set.Set Char
type MapOfSets = Map.Map Int CharSet
data DB = DB { _mos :: MapOfSets } deriving (Show, Eq)
makeLenses ''DB
initDB :: DB
initDB = DB { _mos = Map.fromList (zip [1..5] (repeat Set.empty)) }
add2Map :: Int -> CharSet -> State DB ()
add2Map i cs = mos.ix i %= (Set.union cs)
traverseAll :: Traversal' DB CharSet
traverseAll = mos.traversed
add2MapsAll :: CharSet -> State DB ()
add2MapsAll cs = traverseAll %= (Set.union cs)
-- <problematic part>
{-
traverseSome :: [Int] -> Int -> Traversal' DB MapOfSets
traverseSome ids i = _
add2MapsSome :: [Int] -> CharSet -> State DB ()
add2MapsSome ids cs = mos.(traverseSome ids 2) %= (Set.union cs)
-}
-- </problematic part>
main :: IO ()
main = do
let db = initDB
let bar = Set.fromList ['a'..'g'] :: CharSet
let baz = Set.fromList ['f'..'m'] :: CharSet
let quux = Set.fromList ['n'..'z'] :: CharSet
let db2 = execState (add2Map 5 bar) db
let db3 = execState (add2MapsAll baz) db
-- let db4 = execState (add2MapsSome [1,3] quux) db
print db2
print db3
-- print db4
[1] http://www.haskellforall.com/2013/05/program-imperatively-using-haskell.html