使用镜头测试地图成员资格
Testing for map membership with lenses
使用镜头检查状态图是否有键的惯用方法是什么?这是我目前的尝试:
module Foo where
import Control.Lens
import Data.Map
import Control.Monad.State
import Data.Maybe (isJust)
check :: Int -> StateT (Map Int Int) IO ()
check k = do
present <- use $ at k.to isJust
unless present $ lift $ putStrLn "Not present!"
这可行,但 to isJust
部分感觉有点笨拙...
对于这种特殊情况,请保持简单,不要使用 lens
:
present <- gets (member k)
如果您仍然要使用 lens
,例如需要通过一些字段遍历进入状态才能得到地图,使用uses
:
present <- uses (field1.field2) (member k)
要根据 uses
编写第一个动作,请使用恒等光学 id
:
present <- uses id (member k)
但我不建议无偿这样做。
我只想补充一下,查看某个键是否在地图中 == 检查对该键的遍历 是否具有 目标。
has (ix 5) :: (Ixed s, Num (Index s)) => s -> Bool
use (to $ has $ ix 5) ::
(MonadState s m, Ixed s, Num (Index s)) => m Bool
uses id (has $ ix 5) ::
(MonadState s m, Ixed s, Num (Index s)) => m Bool
但很明显 none 这些都是非常合适的镜头。查看源码,
use = gets . view
所以我们可以这样写,
hasUse :: (MonadState s m) => Getting Any s a -> m Bool
hasUse = gets . has
:t hasUse $ ix 5
hasUse $ ix 5 ::
(MonadState s m, Ixed s, Num (Index s)) => m Bool
我发现的另一种说明方式,
Any present <- uses (ix 5) (const $ Any True)
使用镜头检查状态图是否有键的惯用方法是什么?这是我目前的尝试:
module Foo where
import Control.Lens
import Data.Map
import Control.Monad.State
import Data.Maybe (isJust)
check :: Int -> StateT (Map Int Int) IO ()
check k = do
present <- use $ at k.to isJust
unless present $ lift $ putStrLn "Not present!"
这可行,但 to isJust
部分感觉有点笨拙...
对于这种特殊情况,请保持简单,不要使用 lens
:
present <- gets (member k)
如果您仍然要使用 lens
,例如需要通过一些字段遍历进入状态才能得到地图,使用uses
:
present <- uses (field1.field2) (member k)
要根据 uses
编写第一个动作,请使用恒等光学 id
:
present <- uses id (member k)
但我不建议无偿这样做。
我只想补充一下,查看某个键是否在地图中 == 检查对该键的遍历 是否具有 目标。
has (ix 5) :: (Ixed s, Num (Index s)) => s -> Bool
use (to $ has $ ix 5) ::
(MonadState s m, Ixed s, Num (Index s)) => m Bool
uses id (has $ ix 5) ::
(MonadState s m, Ixed s, Num (Index s)) => m Bool
但很明显 none 这些都是非常合适的镜头。查看源码,
use = gets . view
所以我们可以这样写,
hasUse :: (MonadState s m) => Getting Any s a -> m Bool
hasUse = gets . has
:t hasUse $ ix 5
hasUse $ ix 5 ::
(MonadState s m, Ixed s, Num (Index s)) => m Bool
我发现的另一种说明方式,
Any present <- uses (ix 5) (const $ Any True)