Haskell语言学习笔记(38)Lens(1)
Lens
Lens是一个接近语言级别的库,使用它可以方便的读取,设置,修改一个大的数据结构中某一部分的值。
view, over, set
Prelude> :m +Control.Lens
Prelude Control.Lens> view _1 ("abc", "def")
"abc"
Prelude Control.Lens> over _1 (++ "!!!") ("abc", "def")
("abc!!!","def")
Prelude Control.Lens> set _1 "!!!" ("abc", "def")
("!!!","def")
Prelude Control.Lens> view _2 ("abc", "def")
"def"
这里 _1, _2 则相当于元组的属性名,在 Lens 库中被称为 lens。
view 是一个 Getting,相当于Java语言中用来读取属性的 .getXXX()。
over 以及 set 是一个 Setting,相当于Java语言中用来设置属性的 .setXXX()。
view l s 读取数据结构 s 中字段 l' 的值。
set l s 设置数据结构 s 中字段 l' 的值。
而 over l f s 则通过调用函数 f 修改数据结构 s 中字段 l' 的值。
view, over, set的操作符版本
Prelude> :m +Control.Lens
Prelude Control.Lens> ("abc", "def") ^. _1
"abc"
Prelude Control.Lens> ("abc", "def") & _1 %~ (++ "!!!")
("abc!!!","def")
Prelude Control.Lens> ("abc", "def") & _1 .~ "!!!"
("!!!","def")
Prelude Control.Lens> ("abc", "def") ^. _2
"def"
Prelude Control.Lens> _2 %~ (++ "***") $ ("abc", "def")
("abc","def***")
Prelude Control.Lens> _2 .~ "***" $ ("abc", "def")
("abc","***")
view l s ≡ s ^. l
set l v s ≡ l .~ v $ s ≡ s & l .~ v
over l f s ≡ l %~ f $ s ≡ s & l %~ f
view, over, set 的 State 版本
Prelude Control.Lens Control.Monad.State> evalState (use _1) ("abc","def")
"abc"
Prelude Control.Lens Control.Monad.State> execState (do _1 .= "!!!"; _2 .= "***") ("abc", "def")
("!!!","***")
Prelude Control.Lens Control.Monad.State> execState (do _1 %= (++ "!!!"); _2 %= (++ "***")) ("abc", "def")
("abc!!!","def***")
preview, review
Prelude Control.Lens> view _Left (Left "abc")
"abc"
Prelude Control.Lens> view _Right (Right "abc")
"abc"
Prelude Control.Lens> view _Just (Just "abc")
"abc"
Prelude Control.Lens> preview _Left (Left "abc")
Just "abc"
Prelude Control.Lens> review _Left "abc"
Left "abc"
- preview 和 review 函数处理 Either 这样的和类型
preview 函数向上走一个分支。
review 函数向下走一个分支。
preview, review 的操作符版本
Prelude Control.Lens> Left "abc" ^?! _Left
"abc"
Prelude Control.Lens> Left "abc" ^? _Left
Just "abc"
Prelude Control.Lens> Right "abc" ^? _Left
Nothing
Prelude Control.Lens> Right "abc" ^? _Right
Just "abc"
Prelude Control.Lens> _Left # "abc"
Left "abc"
preview l x ≡ x ^? l
review l x ≡ l # x
toListOf 及其操作符版本
Prelude Control.Lens> toListOf traverse [1,2,3]
[1,2,3]
Prelude Control.Lens> toListOf (traverse.traverse) [[1,2],[3]]
[1,2,3]
Prelude Control.Lens> toListOf both (1,2)
[1,2]
Prelude Control.Lens> toListOf _1 (4, 1)
[4]
Prelude Control.Lens> [[1,2],[3]] ^..traverse.traverse
[1,2,3]
Prelude Control.Lens> (1,2) ^..both
[1,2]
Prelude Control.Lens> (4, 1) ^.._2
[1]
to
Prelude Control.Lens> view (_1 . to negate) (3,5)
-3
Prelude Control.Lens> (3,5)^._1.to negate
-3
Prelude Control.Lens> views _1 negate (3,5)
-3
Prelude Control.Lens Control.Monad.State> evalState (use (_1 . to negate)) (3,5)
-3
Prelude Control.Lens Control.Monad.State> evalState (uses _1 negate) (3,5)
-3
Prelude Control.Lens> preview (_Just .to (+2)) (Just 3)
Just 5
Prelude Control.Lens> previews _Just (+2) (Just 3)
Just 5
to 操作符可以把普通函数提升为 Getter。
view + to = views
use + to = uses
preview + to = previews
mapped
Prelude Control.Lens> over mapped (+1) [1,2,3]
[2,3,4]
Prelude Control.Lens> set mapped 5 [1,2,3]
[5,5,5]
Prelude Control.Lens> over (mapped._1) (+1) [(1,2),(3,4)]
[(2,2),(4,4)]
Prelude Control.Lens> set (mapped.mapped) 5 [[1],[2]]
[[5],[5]]
Prelude Control.Lens> [[1],[2]] & mapped.mapped .~ 5
[[5],[5]]
Prelude Control.Lens> mapped %~ (+1) $ [1,2,3]
[2,3,4]
mapped 操作符可以把普通函数提升为 Functor。
ix
Prelude Control.Lens> [1,2,3] ^? ix 1
Just 2
Prelude Control.Lens> [1,2,3] ^?! ix 1
2
Prelude Control.Lens> [1,2,3] & (ix 1) .~ 20
[1,20,3]
at
relude Control.Lens> import qualified Data.Map as Map
Prelude Control.Lens Map> Map.fromList [(1,"world")] ^.at 1
Just "world"
Prelude Control.Lens Map> Map.fromList [(1,"world")] ^.ix 1
"world"
Prelude Control.Lens Map> at 1 ?~ "hello" $ Map.empty
fromList [(1,"hello")]
Prelude Control.Lens Map> ix 1 ?~ "hello" $ Map.empty
fromList []
traverse
Prelude Control.Lens> [[1], [2], [3]] ^. traverse
[1,2,3]
Prelude Control.Lens> [1,2,3] ^.. traverse
[1,2,3]
Prelude Control.Lens> [[1], [2], [3]] ^.. traverse . traverse
[1,2,3]
non
Prelude Control.Lens> Just 3 ^. non 1
3
Prelude Control.Lens> Nothing ^. non 1
1
参考链接
Haskell/Lenses and functional references
Control.Lens.Tutorial
A Little Lens Starter Tutorial
Haskell语言学习笔记(38)Lens(1)的更多相关文章
- Haskell语言学习笔记(88)语言扩展(1)
ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...
- Haskell语言学习笔记(44)Lens(2)
自定义 Lens 和 Isos -- Some of the examples in this chapter require a few GHC extensions: -- TemplateHas ...
- Haskell语言学习笔记(79)lambda演算
lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...
- Haskell语言学习笔记(69)Yesod
Yesod Yesod 是一个使用 Haskell 语言的 Web 框架. 安装 Yesod 首先更新 Haskell Platform 到最新版 (Yesod 依赖的库非常多,版本不一致的话很容易安 ...
- Haskell语言学习笔记(20)IORef, STRef
IORef 一个在IO monad中使用变量的类型. 函数 参数 功能 newIORef 值 新建带初值的引用 readIORef 引用 读取引用的值 writeIORef 引用和值 设置引用的值 m ...
- Haskell语言学习笔记(39)Category
Category class Category cat where id :: cat a a (.) :: cat b c -> cat a b -> cat a c instance ...
- Haskell语言学习笔记(64)Lens(4)
安装 lens-tutorial Control.Lens.Tutorial $ cabal install lens-tutorial Installed lens-tutorial-1.0.3 P ...
- Haskell语言学习笔记(56)Lens(3)
手动计算(view, over, set, to, _1) view l = getConst . l Const over l f = runIdentity . l (Identity . f) ...
- Haskell语言学习笔记(72)Free Monad
安装 free 包 $ cabal install free Installed free-5.0.2 Free Monad data Free f a = Pure a | Free (f (Fre ...
随机推荐
- JVM 之:Class 类文件结构
类文件结构 Class 文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在 Class 文件中,中间没有添加任何分隔符,这使得整个 Class 文件中存储的内容几乎全部都是 ...
- centos yum安装PHP5.5,5.6,7.0
默认的版本太低了,手动安装有一些麻烦,想采用Yum安装的可以使用下面的方案:1.检查当前安装的PHP包yum list installed | grep php如果有安装的PHP包,先删除他们 yum ...
- 转:使用JMeter创建数据库(Mysql)测试
我的环境:MySQL:mysql-essential-5.1.51-win32 jdbc驱动:我已经上传到csdn上一个:http://download.csdn.net/source/3451945 ...
- Angularjs 事件指令
1. 点击事件 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" ...
- 使用gulp 合并压缩打包,实时监控文件,实现本地server
今天不讲webpack,就说说gulp是怎么进行压缩合并打包 首先你的安装gulp : npm install gulp -g --save-dev 然后最基本的你因该知道gulp 的四个方法, gu ...
- 使用scrapy框架爬取自己的博文
scrapy框架是个比较简单易用基于python的爬虫框架,http://scrapy-chs.readthedocs.org/zh_CN/latest/ 这个是不错的中文文档 几个比较重要的部分: ...
- 【数据库】Eclipse连接MySQL数据库
我的环境:MySQL:mysql-essential-5.1.51-win32 jdbc驱动:我已经上传到csdn上一个:http://download.csdn.net/detail/paulwin ...
- 【Spring学习笔记-MVC-1.0】Spring MVC架构介绍
作者:ssslinppp 1. 核心架构图 2. 核心架构的具体流程步骤 3. 具体的核心开发步骤 4. 常用注解 5. <mvc:annotation-driven>配置 6 ...
- 【Spring学习笔记-MVC-4】SpringMVC返回Json数据-方式2
<Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...
- 导入wordpress数据库到mysql报错
mysql字符集编码错误的导入数据会提示错误了,这个和插入数据一样如果保存的数据与mysql编码不一样那么肯定会出现导入乱码或插入数据丢失的问题,下面我们一起来看一个例子. 恢复数据库报错:由于字符集 ...