haskell - 使用 Lenses 用来自 IO 的数据填充某些复杂结构的正确方法是什么?
问题描述
{- Some code to illustrate what I mean: -}
module Main where
import System.IO
import Control.Monad
import Control.Lens
import Data.UUID
import Data.UUID.V4
-- I have complex data structure (initially, JSON) and I can use
-- Data.Aeson.Lens to work with this structure. It's pretty comfortble
-- in most cases. But let's suppose we have broken data structure.
-- Instead of "a" I need to have unique key. Easiest way is to use GUID.
ds = [ [("a", "z"),("a", "x"),("a", "c")]
, [("a", "v"),("a", "b"),("a", "n")]
, [("a", "m"),("a", ","),("a", ".")]
]
-- So that's how we can get unique ID.
getId :: IO String
getId = toString <$> nextRandom
main :: IO ()
main = do
-- To insert unique ID I can use a awkward way like this:
-- generate pool of ids that is big enough.
let count = length $ ds ^.. traversed <.> traversed
ids <- forM [0..count * count] $ const getId
-- use Indexed Lens to have list of IDs for each data structure level
-- and insert ID from pre generated list where I need it
let ds' = ds & traversed <.> traversed %@~
(\(i1, i2) v -> v & _1 %~
(\v' -> (ids !! (i1 * count + i2)) ++ v'))
print ds'
-- It works. But I wonder if there is some better way to do the same.
解决方案
是的,有更好的方法。你只是错过了一些组合镜头提供的东西。我建议traverseOf
,虽然它在镜头库中还有其他几个别名......而且所有这些别名都只是实现id
......
ds' <- traverseOf (traverse . traverse . _1) (const getId) ds
推荐阅读
- azure-devops - DevOps 发布错误:不允许 EPERM 操作
- python - 遍历 Pandas 数据框中的列表并总结其他列
- c++ - 计算器程序无法编译
- android - mergeDebugResources 错误 - 如何解决?
- c++ - 在 Travis-CI 上使用 Conan 和 Python3
- hadoop-yarn - Yarn local-dirs - 每个节点设置
- mule - 使用 dataweave 2.0 将 xml 转换为 csv
- python - 将一个数字分成 3 个部分
- python - 如何在 python 中使用 Spinnaker 从点灰色相机获取彩色图像?
- puppet - 将日志文件从代理复制到主木偶