Dre*_*rew 7 haskell lenses haskell-lens
我经常发现自己使用这种模式:
do
let oldHeaders = mail ^. headers
put $ (headers .~ (insert header value oldHeaders)) mail
Run Code Online (Sandbox Code Playgroud)
这看起来像Control.Lens应该能做的事情,但我想我还没有找到合适的操作员.有没有更好的办法?另外,在这段代码中我还应该做些什么吗?
J. *_*son 11
您可以使用Lenses和Traversals 链直接访问内部标头值并更新它.
put $ mail & headers . at header ?~ value
Run Code Online (Sandbox Code Playgroud)
请注意,这(?~)只是简写\lens value -> lens .~ Just value.的Just是需要指出的at是,我们想,如果不存在的话插入值镜头.
如果mail在第一行来自像这样的州monad
do
mail <- get
let oldHeaders = mail ^. headers
put $ (headers .~ (insert header value oldHeaders)) mail
Run Code Online (Sandbox Code Playgroud)
然后用它来写它就更简单了 modify :: MonadState s m => (s -> s) -> m ()
modify (headers . at header ?~ value)
Run Code Online (Sandbox Code Playgroud)
正如ØrjanJohansen在评论中所建议的那样,可以写成最简洁的
headers . at header ?= value
Run Code Online (Sandbox Code Playgroud)
你通常不会需要get和put明确在State使用镜头时单子.在您的情况下,您可以使用运算符?=直接更新状态:
example = do
headers . at header ?= value
Run Code Online (Sandbox Code Playgroud)
您还可以使用以下功能修改任何镜头%=:
example2 = do
headers %= insert header value
Run Code Online (Sandbox Code Playgroud)