Chris Stryczynski

Software Developer / Consultant

How to modify a dynamic nested YAML object with Haskell

Posted on: 04/03/2018

So Haskell has an awesome YAML library (based off the famous JSON library), however I’m not sure if there is a ‘Lens’ binding for it - like the aeson library, I’m also not that familiar with lens, so thought I’d just do this manually.

I didn’t find any solution online so I’m posting it here.

I couldn’t use the usual toYAML / fromYAML as the YAML would be dynamic.

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE LambdaCase #-}

module Deployment where

import Data.Yaml as Yaml
import Data.HashMap.Strict as M
import Data.Text

modifyObject :: Text -> (Object -> Maybe Object) -> Object -> Maybe Object
modifyObject k f o = do
  subsetObjectX <- (M.lookup k o) >>= lookupObject >>= f
  return $ M.insert k (Object subsetObjectX) o

lookupObject :: Value -> Maybe Object
lookupObject (Object x) = Just x
lookupObject _ = Nothing

modifyObjectNested :: [Text] -> (Object -> Maybe Object) -> Object -> Maybe Object
modifyObjectNested (x:[]) f = modifyObject x f
modifyObjectNested (x:xs) f = modifyObject x (modifyObjectNested xs f)
modifyObjectNested [] _ = Just

createDeployment :: Object -> Text -> Maybe Object
createDeployment v appId = modifyObjectNested ["metadata", "labels"] (Just . M.insert "appId" (Yaml.String appId)) v

The above can be used with createDeployment deploymentConfig "test" and will modify the below:

metadata:
  name: diyapp
  labels:
    appId: thisHasToBeReeplaced

To

metadata:
  name: diyapp
  labels:
    appId: test
Comments

No comments, yet!

Submit a comment