我想减少以下锅炉板代码,但不使用镜头(Data.Label)。我怎么能最好地做到这一点?
data Qcfg = Qcfg { qthresh :: Int, tdelay :: Rational, cwpsq :: TPSQ, cwmap :: TMap, cwchan :: TChan String }
getQthresh = do
c <- ask
return (qthresh c)
getDelay = do
c <- ask
return (tdelay c)
getTMap = do
c <- ask
return (cwmap c)
getTPsq = do
c <- ask
return (cwpsq c)
getTChan = do
c <- ask
return (cwchan c)
答案 0 :(得分:8)
这些只是fmap的案例。这些都是等价的:
getQthresh = qthresh <$> ask
getQthresh'' = fmap qthresh ask
getQthresh''' = liftM qthresh ask
getQthresh' = do
c <- ask
return (qthresh c)
Data.Functor
/ Control.Applicative
版<$>
是您想要的版本;如果你考虑一下,根本就没有样板。而你确实在为每个访问者浪费空间编写功能;你只是一种新的方式来应用fmap/<$>
给你的访问者。如果你永远在写<$> ask
,你可以定义
get field = field <$> ask
也许这就是你现在想到的,我想到了它。然后
get qthresh
将与您的
相同getQthresh
和其他领域类似。当然你可以用你的monadic方式定义这个get
(注意State有不同的一个):
get field = do
c <- ask
return (field c)
对于Reader
的特定情况,asks f
为fmap f ask
,gets
为State
,但我提出的问题是关于将“访问者”提升为仿函数或monad,因为do {x <- action; return (f x)}
只是f <$> action