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 ...
随机推荐
- opencv读取并播放avi视屏
视屏的本质是一些静态的图像的集合,opencv可以不断读取视屏中的图片,显示,就产生了类似电影的效果. 这样也就可以通过opencv对实时的视屏流进行处理了. #include "stdaf ...
- HighCharts定时刷新图表
假设图表容器的id为exChart,如下: <div style="height:450px;" id="chart"> 1. 首先在serie ...
- 使用纯生js操作cookie
前段时间做项目的时候要使用js操作cookie,jquery也有相应的插件,不过还是觉得纯生的js比较好,毕竟不依赖jq. //获得coolie 的值 function cookie(name) { ...
- DataSet和DataTable有用的方法
每一个DataSet都是一个或多个DataTable 对象的集合(DataTable相当于数据库中的表),这些对象由数据行(DataRow).数据列(DataColumn).字段名(Column Na ...
- POSIX 消息队列 之 概述 链接方式
NAMEmq_overview —— POSIX消息队列概述 DESCRIPTIONPOSIX消息队列允许进程以消息的形式交换数据.此API与System V消息队列(msgget(2),msgsnd ...
- BASIC-5_蓝桥杯_查找整数
示例代码: #include <stdio.h>#include <stdlib.h> int main(void){ int n = 0 , key = 0 , count ...
- Spring Boot + Jpa(Hibernate) 架构基本配置
本文转载自:https://blog.csdn.net/javahighness/article/details/53055149 1.基于springboot-1.4.0.RELEASE版本测试 2 ...
- 实验七 c字符数组和字符串函数
7.1 #include<stdio.h>#include<string.h> int main(){ char a[40]; int i; gets(a); //输入字符串进 ...
- 6.28笔记-servlet3.0注解配置、文件上传、过滤器、监听器
一.servlet3.0注解配置 使用javaEE6.0 支持servlet3.0 value的值就是访问路径 urlPatterns的值也是访问路径 @WebServlet(name="D ...
- php字符串类型讲解
PHP 支持八种原始类型(type). 四种标量类型: string(字符串) integer(整型) float(浮点型,也作 double ) boolean(布尔型) 两种复合类型: array ...