3 ms·
Let's say you've serialized a tree structure of versioned data as JSON. Branches are arrays and leaves are objects. data OTree = Obj Object | Node (Data.Ve
by tel 13y ago
Let's say you've serialized a tree structure of versioned data as JSON. Branches are arrays and leaves are objects.
data OTree = Obj Object | Node (Data.Vector.Vector OTree)
instance FromJSON OTree where
parseJSON (Array as) = Node <$> traverse parseJSON as
parseJSON (Object o) = return (Obj o)
parseJSON _ = fail "OTrees are objects and arrays"
instance ToJSON OTree where
toJSON (Node as) = Array (fmap toJSON as)
toJSON (Obj o) = Object o
Now some of these objects have keyed "version"s which are arrays of semantic versioning numbers. Write a function which decodes and re-encodes a new tree with each of these semantic versioning numbers incremented at the patch level. If the version isn't in that format, just ignore it.
In Haskell you'd want to write a generic traversal over the objects of the tree useful whenever you want even access to the contained elements.
eachObj :: Traversal' OTree Object
eachObj inj (Obj o ) = Obj <$> inj o
eachObj inj (Node as) = Node <$> traverse (eachObj inj) as
And then here's the finale, the actual lens code specific to the task.
upgrade = _JSON . eachObj . ix "version" . _Array . ix 2 . _Number +~ 1
- bjourne 13y agoThat's a contrived example and not "real source code." Furthermore you are leaving so many symbols undefined that it is hard to see what is going on. Where does 'traverse' come from? Nevertheless, here is how you would do it in python: https://gist.github.com/bjourne/6219037 https://gist.github.com/bjourne/6219037
- tel 13y agoIt's extracted, not contrived. Updating nested attributes on a tree of objects as a nice one-liner. The most contrived bits were that I didn't use the built in tree type so I had to define more stuff explicitly. Traverse comes from Data.Traverable but is exported with lens as lens can be seen as a generalization of traverse.