You can use the Lens es and Traversal chain to directly access the internal value of the header and update it.
put $ mail & headers . at header ?~ value
Note that (?~) Is simply abbreviated for \lens value -> lens .~ Just value . Just needs to point to the at object we want to insert if it does not already exist.
If the mail in the first line comes from a state monad, such as
do mail <- get let oldHeaders = mail ^. headers put $ (headers .~ (insert header value oldHeaders)) mail
itβs easier to write that with modify :: MonadState sm => (s -> s) -> m ()
modify (headers . at header ?~ value)
Which, as suggested by Γrjan Johansen in the comments, can be written most reliably as
headers . at header ?= value
source share