安装 lens-tutorial

Control.Lens.Tutorial

$ cabal install lens-tutorial
Installed lens-tutorial-1.0.3
Prelude> :m +Control.Lens.Tutorial
Prelude Control.Lens.Tutorial>
{-# LANGUAGE TemplateHaskell   #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-} import Control.Applicative (Applicative)
import Control.Lens hiding (element)
import Data.Foldable (Foldable)
import Data.Monoid (Monoid) data Atom = Atom { _element :: String, _point :: Point } deriving (Show)
data Point = Point { _x :: Double, _y :: Double } deriving (Show)
data Molecule = Molecule { _atoms :: [Atom] } deriving (Show)
data Pair a = Pair a a deriving (Functor, Foldable, Traversable)
makeLenses ''Atom
makeLenses ''Point
makeLenses ''Molecule shiftAtomX :: Atom -> Atom
shiftAtomX = over (point . x) (+ 1) shiftMoleculeX :: Molecule -> Molecule
shiftMoleculeX = over (atoms . traverse . point . x) (+ 1) shift :: ASetter' a Double -> a -> a
shift lens = over lens (+ 1)

Lens 的类型

type Lens' a b = forall f . Functor f => (b -> f b) -> (a -> f a)
type ASetter' a b = (b -> Identity b) -> (a -> Identity a)
-- ... equivalent to: (b -> b) -> (a -> a)
type Getting b a b = (b -> Const b b) -> (a -> Const b a)
-- ... equivalent to: (b -> b ) -> (a -> b )
-- (a -> b ) -- +-- Bigger type
-- |
-- v
Lens' bigger smaller
-- ^
-- |
-- +-- Smaller type within the bigger type
element :: Lens' Atom String
point :: Lens' Atom Point
x :: Lens' Point Double
y :: Lens' Point Double -- lens :: (a -> b) -> (a -> b -> a) -> Lens' a b
point2 :: Lens' Atom Point
point2 = lens _point (\atom newPoint -> atom { _point = newPoint }) -- point3 :: Lens' Atom Point
point3 :: Functor f => (Point -> f Point) -> Atom -> f Atom
point3 k atom = fmap (\newPoint -> atom { _point = newPoint }) (k (_point atom))
(.) :: Lens' a b -> Lens' b c -> Lens' a c
type Lens' a b = forall f . Functor f => (b -> f b) -> (a -> f a)
(.) :: Functor f
=> ((b -> f b) -> (a -> f a))
-> ((c -> f c) -> (b -> f b))
-> ((c -> f c) -> (a -> f a))
point :: Lens' Atom Point
x :: Lens' Point Double
point . x :: Lens' Atom Double view (point . x) :: Atom -> Double
over (point . x) :: (Double -> Double) -> (Atom -> Atom)
view :: Lens' a b -> a -> b
over :: Lens' a b -> (b -> b) -> a -> a
set :: Lens' a b -> b -> a -> a
set lens b = over lens (\_ -> b) view (lens1 . lens2) = (view lens2) . (view lens1)
view id = id
over (lens1 . lens2) = (over lens1) . (over lens2)
over id = id
type Traversal' a b = forall f . Applicative f => (b -> f b) -> (a -> f a)
type Lens' a b = forall f . Functor f => (b -> f b) -> (a -> f a) atoms :: Traversal' Molecule [Atom]
element :: Traversal' Atom String
point :: Traversal' Atom Point
x :: Traversal' Point Double
y :: Traversal' Point Double traverse :: Traversable t => Traversal' (t a) a
traverse :: (Applicative f, Traversable t) => (a -> f a) -> t a -> f (t a)
traverse :: Traversal' [a] a traverse :: Traversal' (Pair a) a
over traverse :: (a -> a) -> (Pair a -> Pair a)
over traverse (+ 1) (Pair 3 4) = Pair 4 5 (.) :: Traversal' a b -> Traversal' b c -> Traversal' a c
(.) :: Applicative f
=> ((b -> f b) -> (a -> f a))
-> ((c -> f c) -> (b -> f b))
-> ((c -> f c) -> (a -> f a)) -- Remember that `atoms`, `point`, and `x` are also `Traversal'`s
atoms :: Traversal' Molecule [Atom]
traverse :: Traversal' [Atom] Atom
point :: Traversal' Atom Point
x :: Traversal' Point Double -- Now compose them
atoms :: Traversal' Molecule [Atom]
atoms . traverse :: Traversal' Molecule Atom
atoms . traverse . point :: Traversal' Molecule Point
atoms . traverse . point . x :: Traversal' Molecule Double over (atoms . traverse . point . x)
:: (Double -> Double) -> (Molecule -> Molecule)
toListOf (atoms . traverse . point . x)
:: Molecule -> [Double] toListOf :: Traversal' a b -> a -> [b]
over :: Traversal' a b -> (b -> b) -> a -> a
set :: Traversal' a b -> b -> a -> a
set traversal b = over traversal (\_ -> b) toListOf (traversal1 . traversal2) = (toListOf traversal1) >=> (toListOf traversal2)
toListOf id = return

参考链接

Taking a Close look at Lenses

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

  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语言学习笔记(38)Lens(1)

    Lens Lens是一个接近语言级别的库,使用它可以方便的读取,设置,修改一个大的数据结构中某一部分的值. view, over, set Prelude> :m +Control.Lens 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. 关于 Cookie-free Domains (为什么将静态图片,js,css存放到单独的域名?)

    这篇文章对高性能web开发具有参考性:http://developer.yahoo.com/performance/rules.html 本文主要描述使用裸域名做网站主域名时,如何用子域名做 cook ...

  2. ASP.NET Core 2.0 使用支付宝PC网站支付实现代码(转)

    最近在使用ASP.NET Core来进行开发,刚好有个接入支付宝支付的需求,百度了一下没找到相关的资料,看了官方的SDK以及Demo都还是.NET Framework的,所以就先根据官方SDK的源码, ...

  3. 好强大的vim配置文件

    原文链接 http://www.cnblogs.com/ma6174/archive/2011/12/10/2283393.html

  4. phonegap 2.9 IOS Xcode 搭建环境

    一:下载phoneGap2.9和安装Xcode5(目前最新版) 选择2.9是因为3.0以上坑爹版本编译神马的要在有网络情况. 二: 下载phonegap后解压到你的指定文件夹中,解压后找到create ...

  5. 【ActiveMQ入门-5】ActiveMQ学习-Queue与Topic的比较

    Queue与Topic的比较 1.JMS Queue执行load balancer语义: 一条消息仅能被一个consumer收到. 如果在message发送的时候没有可用的consumer,那么它将被 ...

  6. jstack可以定位到线程堆栈

    java命令--jstack 工具 JVM调优之jstack找出最耗cpu的线程并定位代码 jstack可以定位到线程堆栈,根据堆栈信息我们

  7. [UE4]OnComponentBeginOverlap.AddDynamic 的编译错误

    以 Character 类为例,假设有 PacManCharacter 派生自 Character类首先在 PacManCharacter.h 头文件中添加碰撞函数的声明: OnCollision 为 ...

  8. 取得 Ajax 返回参数

    ajax 函数,p1 为正常参数 function ExecWebFunction(callback,p1) { $.ajax({ type: "POST", contentTyp ...

  9. linux进程与线程的区别【转】

    知乎上总结: "linux使用的1:1的线程模型,在内核中是不区分线程和进程的,都是可运行的任务而已.fork调用clone(最少的共享),pthread_create也是调用clone(最 ...

  10. 【C++11新特性】 - 空间配置allocator类

    原文链接: http://blog.csdn.net/Xiejingfa/article/details/50955295 今天我们来讲讲C++的allocator类. C++提供了new和delet ...