2012-06-19 162 views
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) 
+8

是'getDelay =詢問tdelay'等足夠好嗎? –

+0

@DanielFischer我希望將它以某種方式組合成一個簡單的功能。 –

+0

@JFritsch,一個功能?所以你會寫'foo < - getField',Haskell只會猜測你的意思?你的意思是它應該工作? – dflemstr

回答

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(注意該國去與一個不同)在一元路:

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

對於Readerasks f這是fmap f ask,同樣getsState的具體情況,但我這個問題是關於'提升'訪問器到函子或monad中的,因爲它看起來並不簡單,只是f <$> action