Updating inside nested records

I’ve been playing with dhall-kubernetes a bit recently, and I’m finding myself repeating the same snippet of code:

let myDeployment -- Deployment is an example, it could be any kubernetes type really
	: types.Deployment
	=   defaults.Deployment
	  ⫽ { metadata =
			  defaults.ObjectMeta
			⫽ { namespace =
				  Some "default"
			  , name =
				  "prometheus-operator"
			  , labels =
				  ./commonLabels.dhall
			  }
-- ...

Basically, I want to override the default values of metadata.name, metadata.namespace and metadata.labels. In order to do this, I need to reference defaults.ObjectMeta (or possibly defaults.Deployment.metadata) to get the rest of the metadata fields, which i don’t want to change.

It feels clunky to have to reference the defaults for the metadata field when I have already set defaults for the whole data structure. When using , I can’t skip defaults.ObjectMeta because is non-recursive and will replace the whole record. I thought I could try instead, which is recursive, but it doesn’t allow replacing fields which already exist (in this example, I can use to set name but not namespace or labels, which have defaults.)

In other languages, I’m used to being able to update a single value within a nested data structure without so much wrangling. For example, Clojure’s assoc-in function allows you to upsert a value at an arbitrary path in a nested data structure. (side note: it even plays nicely if some of the nested layers are vectors rather than maps)

It feels like there could be a recursive variant of which might meet my needs (though I can see that specifying its behaviour might be tricky). Is this something which has previously been considered and rejected? It would look something like this:

let myDeployment -- Deployment is an example, it could be any kubernetes type really
	: types.Deployment
	=   defaults.Deployment
	  /// { metadata =
			   { namespace =
				  Some "default"
			  , name =
				  "prometheus-operator"
			  , labels =
				  ./commonLabels.dhall
			  }
-- ...

See this discussion:

1 Like