以一流價值捆綁在一起的吸氣劑和二聚體被稱爲透鏡。這樣做有相當多的軟件包;最受歡迎的是data-lens和fclabels。這個previous SO question是一個很好的介紹。
這兩個庫都支持使用Template Haskell(使用數據鏡頭,爲便攜性提供an additional package)從記錄定義中獲取鏡頭。你的榜樣將被表示爲(使用數據鏡頭語法):
setL idxF_s (b ^. idL_s) a
(或等價:idxF_s ^= (b ^. idL_s) $ a
)
你可以,當然,通過改變他們的getter和setter一起變換鏡頭的通用方式:
-- I don't know what swap_by_sign is supposed to do.
negateLens :: (Num b) => Lens a b -> Lens a b
negateLens l = lens get set
where
get = negate . getL l
set = setL l . negate
(或等效:negateLens l = iso negate negate . l
)
在屬l,我會建議在任何時候不得不處理任何不平凡的記錄處理時使用鏡頭;它們不僅極大地簡化了記錄的純轉換,而且這兩個軟件包都包含便捷功能,用於使用鏡頭訪問和修改狀態monad的狀態,這非常有用。 (對於數據的鏡頭,你會希望使用data-lens-fd包在任何MonadState
使用這些方便的功能;再次,他們是在一個單獨的包的可移植性。)
使用時無論是包,你應該開始您的模塊:
import Prelude hiding (id, (.))
import Control.Category
這是因爲他們使用的前奏的id
和(.)
功能廣義形式 - id
可以作爲任何值鏡頭本身(而不是所有的有用的,誠然)和(.)
用於組成鏡片(例如, getL (fieldA . fieldB) a
與getL fieldA . getL fieldB $ a
相同)。較短的negateLens
定義使用此。
指向成員操作符的指針不是C而是C++。重新標記。 – 2012-02-04 20:08:21