我发现自己经常使用这种模式:
do
let oldHeaders = mail ^. headers
put $ (headers .~ (insert header value oldHeaders)) mail
这似乎是 Control.Lens 应该能够做的事情,但我想我还没有找到合适的操作员。有没有更好的办法?另外,在这段代码中我还应该做些什么不同的事情吗?
我发现自己经常使用这种模式:
do
let oldHeaders = mail ^. headers
put $ (headers .~ (insert header value oldHeaders)) mail
这似乎是 Control.Lens 应该能够做的事情,但我想我还没有找到合适的操作员。有没有更好的办法?另外,在这段代码中我还应该做些什么不同的事情吗?
您可以使用Lens
es 和Traversal
s 链直接访问内部标头值并对其进行更新。
put $ mail & headers . at header ?~ value
请注意,这(?~)
只是\lens value -> lens .~ Just value
. Just
需要向镜头指示我们at
要插入一个值(如果它尚不存在)。
如果mail
第一行来自这样的状态单子
do
mail <- get
let oldHeaders = mail ^. headers
put $ (headers .~ (insert header value oldHeaders)) mail
那么用modify :: MonadState s m => (s -> s) -> m ()
modify (headers . at header ?~ value)
正如 Ørjan Johansen 在评论中所建议的那样,可以最简洁地写成
headers . at header ?= value