1

我想减少以下样板代码,但不使用镜头(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)
4

1 回答 1

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

对于其他领域也是如此。当然,你可以get用你的一元方式定义这个(注意 State 使用不同的):

get field = do
   c <- ask
   return (field c)

对于Readerthere is asks fwhich isfmap f askgetsfor的具体情况State,但我认为这个问题是关于将访问器“提升”到 functor 或 monad 中,因为这似乎并不do {x <- action; return (f x)}简单f <$> action

于 2012-06-19T13:43:29.163 回答