npo*_*cop 5 haskell lenses haskell-lens
我有一个从A类到B类的总映射.
import qualified Data.Map as M
import Data.Maybe
tmGet k m = fromJust $ M.lookup k m
tmSet k v = M.insert k v
Run Code Online (Sandbox Code Playgroud)
我用它Data.Map作为一个示例实现,但它可以是任何东西,例如一个Array甚至是一个Bool索引的元组:
tmGet True = fst
tmGet False = snd
Run Code Online (Sandbox Code Playgroud)
我想要一个tmAt构建镜头的功能:
(42, 665) ^. tmAt True == 42
(42, 665) & tmAt False +~ 1 == (42, 666)
Run Code Online (Sandbox Code Playgroud)
现在的问题是我如何建构tmAt出来tmGet和tmSet(或tmModify)?
如果您查看Control.Lens 模块的文档,就会发现镜头包不同部分的非常方便的图像。既然你想构造一个Lens,你可以看一下Lens图的部分。显示的最上面的函数是
lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b\nRun Code Online (Sandbox Code Playgroud)\n\n这从 getter 和 setter 构造了一个 Lens。
\n\n该函数s -> a是一个 getter \xe2\x80\x93 类型签名的意思是,“如果你给我一个数据结构s,我会a从中选择一个值。” 该s -> b -> t函数是 setter,类型签名的意思是,“如果你给我一个s新值b,我将为你创建一个新结构t。” (类型不同,因为镜头实际上可以改变事物的类型。)
如果你的 getter 是tmGet并且你的 setter 是tmSet,那么你可以用
tmAt :: Boolean -> Lens s t a b\ntmAt b = lens (tmGet b) (tmSet b)\nRun Code Online (Sandbox Code Playgroud)\n\n无论您的实际s、t、a和b参数是什么。在元组的示例中,它将是
tmAt :: Bool -> Lens (a, a) (a, a) a a\nRun Code Online (Sandbox Code Playgroud)\n\n(换句话说,如果你给 Lens 一个函数a -> a,它可以将一个(a, a)-tuple 转换为另一个(a, a)-tuple。)
如果你想花哨一点,也可以重写tmAt为
tmAt = lens <$> tmGet <*> tmSet\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
226 次 |
| 最近记录: |