Lens

Lens是一个接近语言级别的库,使用它可以方便的读取,设置,修改一个大的数据结构中某一部分的值。

view, over, set

  1. Prelude> :m +Control.Lens
  2. Prelude Control.Lens> view _1 ("abc", "def")
  3. "abc"
  4. Prelude Control.Lens> over _1 (++ "!!!") ("abc", "def")
  5. ("abc!!!","def")
  6. Prelude Control.Lens> set _1 "!!!" ("abc", "def")
  7. ("!!!","def")
  8. Prelude Control.Lens> view _2 ("abc", "def")
  9. "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的操作符版本

  1. Prelude> :m +Control.Lens
  2. Prelude Control.Lens> ("abc", "def") ^. _1
  3. "abc"
  4. Prelude Control.Lens> ("abc", "def") & _1 %~ (++ "!!!")
  5. ("abc!!!","def")
  6. Prelude Control.Lens> ("abc", "def") & _1 .~ "!!!"
  7. ("!!!","def")
  8. Prelude Control.Lens> ("abc", "def") ^. _2
  9. "def"
  10. Prelude Control.Lens> _2 %~ (++ "***") $ ("abc", "def")
  11. ("abc","def***")
  12. Prelude Control.Lens> _2 .~ "***" $ ("abc", "def")
  13. ("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 版本

  1. Prelude Control.Lens Control.Monad.State> evalState (use _1) ("abc","def")
  2. "abc"
  3. Prelude Control.Lens Control.Monad.State> execState (do _1 .= "!!!"; _2 .= "***") ("abc", "def")
  4. ("!!!","***")
  5. Prelude Control.Lens Control.Monad.State> execState (do _1 %= (++ "!!!"); _2 %= (++ "***")) ("abc", "def")
  6. ("abc!!!","def***")

preview, review

  1. Prelude Control.Lens> view _Left (Left "abc")
  2. "abc"
  3. Prelude Control.Lens> view _Right (Right "abc")
  4. "abc"
  5. Prelude Control.Lens> view _Just (Just "abc")
  6. "abc"
  7. Prelude Control.Lens> preview _Left (Left "abc")
  8. Just "abc"
  9. Prelude Control.Lens> review _Left "abc"
  10. Left "abc"
  • preview 和 review 函数处理 Either 这样的和类型

    preview 函数向上走一个分支。

    review 函数向下走一个分支。

preview, review 的操作符版本

  1. Prelude Control.Lens> Left "abc" ^?! _Left
  2. "abc"
  3. Prelude Control.Lens> Left "abc" ^? _Left
  4. Just "abc"
  5. Prelude Control.Lens> Right "abc" ^? _Left
  6. Nothing
  7. Prelude Control.Lens> Right "abc" ^? _Right
  8. Just "abc"
  9. Prelude Control.Lens> _Left # "abc"
  10. Left "abc"

preview l x ≡ x ^? l

review l x ≡ l # x

toListOf 及其操作符版本

  1. Prelude Control.Lens> toListOf traverse [1,2,3]
  2. [1,2,3]
  3. Prelude Control.Lens> toListOf (traverse.traverse) [[1,2],[3]]
  4. [1,2,3]
  5. Prelude Control.Lens> toListOf both (1,2)
  6. [1,2]
  7. Prelude Control.Lens> toListOf _1 (4, 1)
  8. [4]
  9. Prelude Control.Lens> [[1,2],[3]] ^..traverse.traverse
  10. [1,2,3]
  11. Prelude Control.Lens> (1,2) ^..both
  12. [1,2]
  13. Prelude Control.Lens> (4, 1) ^.._2
  14. [1]

to

  1. Prelude Control.Lens> view (_1 . to negate) (3,5)
  2. -3
  3. Prelude Control.Lens> (3,5)^._1.to negate
  4. -3
  5. Prelude Control.Lens> views _1 negate (3,5)
  6. -3
  7. Prelude Control.Lens Control.Monad.State> evalState (use (_1 . to negate)) (3,5)
  8. -3
  9. Prelude Control.Lens Control.Monad.State> evalState (uses _1 negate) (3,5)
  10. -3
  11. Prelude Control.Lens> preview (_Just .to (+2)) (Just 3)
  12. Just 5
  13. Prelude Control.Lens> previews _Just (+2) (Just 3)
  14. Just 5

to 操作符可以把普通函数提升为 Getter。

view + to = views

use + to = uses

preview + to = previews

mapped

  1. Prelude Control.Lens> over mapped (+1) [1,2,3]
  2. [2,3,4]
  3. Prelude Control.Lens> set mapped 5 [1,2,3]
  4. [5,5,5]
  5. Prelude Control.Lens> over (mapped._1) (+1) [(1,2),(3,4)]
  6. [(2,2),(4,4)]
  7. Prelude Control.Lens> set (mapped.mapped) 5 [[1],[2]]
  8. [[5],[5]]
  9. Prelude Control.Lens> [[1],[2]] & mapped.mapped .~ 5
  10. [[5],[5]]
  11. Prelude Control.Lens> mapped %~ (+1) $ [1,2,3]
  12. [2,3,4]

mapped 操作符可以把普通函数提升为 Functor。

ix

  1. Prelude Control.Lens> [1,2,3] ^? ix 1
  2. Just 2
  3. Prelude Control.Lens> [1,2,3] ^?! ix 1
  4. 2
  5. Prelude Control.Lens> [1,2,3] & (ix 1) .~ 20
  6. [1,20,3]

at

  1. relude Control.Lens> import qualified Data.Map as Map
  2. Prelude Control.Lens Map> Map.fromList [(1,"world")] ^.at 1
  3. Just "world"
  4. Prelude Control.Lens Map> Map.fromList [(1,"world")] ^.ix 1
  5. "world"
  6. Prelude Control.Lens Map> at 1 ?~ "hello" $ Map.empty
  7. fromList [(1,"hello")]
  8. Prelude Control.Lens Map> ix 1 ?~ "hello" $ Map.empty
  9. fromList []

traverse

  1. Prelude Control.Lens> [[1], [2], [3]] ^. traverse
  2. [1,2,3]
  3. Prelude Control.Lens> [1,2,3] ^.. traverse
  4. [1,2,3]
  5. Prelude Control.Lens> [[1], [2], [3]] ^.. traverse . traverse
  6. [1,2,3]

non

  1. Prelude Control.Lens> Just 3 ^. non 1
  2. 3
  3. Prelude Control.Lens> Nothing ^. non 1
  4. 1

参考链接

Haskell/Lenses and functional references

Control.Lens.Tutorial

A Little Lens Starter Tutorial

Haskell语言学习笔记(38)Lens(1)的更多相关文章

  1. Haskell语言学习笔记(88)语言扩展(1)

    ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...

  2. Haskell语言学习笔记(44)Lens(2)

    自定义 Lens 和 Isos -- Some of the examples in this chapter require a few GHC extensions: -- TemplateHas ...

  3. Haskell语言学习笔记(79)lambda演算

    lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...

  4. Haskell语言学习笔记(69)Yesod

    Yesod Yesod 是一个使用 Haskell 语言的 Web 框架. 安装 Yesod 首先更新 Haskell Platform 到最新版 (Yesod 依赖的库非常多,版本不一致的话很容易安 ...

  5. Haskell语言学习笔记(20)IORef, STRef

    IORef 一个在IO monad中使用变量的类型. 函数 参数 功能 newIORef 值 新建带初值的引用 readIORef 引用 读取引用的值 writeIORef 引用和值 设置引用的值 m ...

  6. Haskell语言学习笔记(39)Category

    Category class Category cat where id :: cat a a (.) :: cat b c -> cat a b -> cat a c instance ...

  7. Haskell语言学习笔记(64)Lens(4)

    安装 lens-tutorial Control.Lens.Tutorial $ cabal install lens-tutorial Installed lens-tutorial-1.0.3 P ...

  8. Haskell语言学习笔记(56)Lens(3)

    手动计算(view, over, set, to, _1) view l = getConst . l Const over l f = runIdentity . l (Identity . f) ...

  9. Haskell语言学习笔记(72)Free Monad

    安装 free 包 $ cabal install free Installed free-5.0.2 Free Monad data Free f a = Pure a | Free (f (Fre ...

随机推荐

  1. JVM 之:Class 类文件结构

    类文件结构 Class 文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在 Class 文件中,中间没有添加任何分隔符,这使得整个 Class 文件中存储的内容几乎全部都是 ...

  2. centos yum安装PHP5.5,5.6,7.0

    默认的版本太低了,手动安装有一些麻烦,想采用Yum安装的可以使用下面的方案:1.检查当前安装的PHP包yum list installed | grep php如果有安装的PHP包,先删除他们 yum ...

  3. 转:使用JMeter创建数据库(Mysql)测试

    我的环境:MySQL:mysql-essential-5.1.51-win32 jdbc驱动:我已经上传到csdn上一个:http://download.csdn.net/source/3451945 ...

  4. Angularjs 事件指令

    1.  点击事件 <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" ...

  5. 使用gulp 合并压缩打包,实时监控文件,实现本地server

    今天不讲webpack,就说说gulp是怎么进行压缩合并打包 首先你的安装gulp : npm install gulp -g --save-dev 然后最基本的你因该知道gulp 的四个方法, gu ...

  6. 使用scrapy框架爬取自己的博文

    scrapy框架是个比较简单易用基于python的爬虫框架,http://scrapy-chs.readthedocs.org/zh_CN/latest/ 这个是不错的中文文档 几个比较重要的部分: ...

  7. 【数据库】Eclipse连接MySQL数据库

    我的环境:MySQL:mysql-essential-5.1.51-win32 jdbc驱动:我已经上传到csdn上一个:http://download.csdn.net/detail/paulwin ...

  8. 【Spring学习笔记-MVC-1.0】Spring MVC架构介绍

    作者:ssslinppp       1. 核心架构图 2. 核心架构的具体流程步骤 3. 具体的核心开发步骤 4. 常用注解 5. <mvc:annotation-driven>配置 6 ...

  9. 【Spring学习笔记-MVC-4】SpringMVC返回Json数据-方式2

    <Spring学习笔记-MVC>系列文章,讲解返回json数据的文章共有3篇,分别为: [Spring学习笔记-MVC-3]SpringMVC返回Json数据-方式1:http://www ...

  10. 导入wordpress数据库到mysql报错

    mysql字符集编码错误的导入数据会提示错误了,这个和插入数据一样如果保存的数据与mysql编码不一样那么肯定会出现导入乱码或插入数据丢失的问题,下面我们一起来看一个例子. 恢复数据库报错:由于字符集 ...