Haskell语言学习笔记(64)Lens(4)
安装 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
参考链接
Haskell语言学习笔记(64)Lens(4)的更多相关文章
- 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语言学习笔记(38)Lens(1)
Lens Lens是一个接近语言级别的库,使用它可以方便的读取,设置,修改一个大的数据结构中某一部分的值. view, over, set Prelude> :m +Control.Lens 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 ...
随机推荐
- 关于 Cookie-free Domains (为什么将静态图片,js,css存放到单独的域名?)
这篇文章对高性能web开发具有参考性:http://developer.yahoo.com/performance/rules.html 本文主要描述使用裸域名做网站主域名时,如何用子域名做 cook ...
- ASP.NET Core 2.0 使用支付宝PC网站支付实现代码(转)
最近在使用ASP.NET Core来进行开发,刚好有个接入支付宝支付的需求,百度了一下没找到相关的资料,看了官方的SDK以及Demo都还是.NET Framework的,所以就先根据官方SDK的源码, ...
- 好强大的vim配置文件
原文链接 http://www.cnblogs.com/ma6174/archive/2011/12/10/2283393.html
- phonegap 2.9 IOS Xcode 搭建环境
一:下载phoneGap2.9和安装Xcode5(目前最新版) 选择2.9是因为3.0以上坑爹版本编译神马的要在有网络情况. 二: 下载phonegap后解压到你的指定文件夹中,解压后找到create ...
- 【ActiveMQ入门-5】ActiveMQ学习-Queue与Topic的比较
Queue与Topic的比较 1.JMS Queue执行load balancer语义: 一条消息仅能被一个consumer收到. 如果在message发送的时候没有可用的consumer,那么它将被 ...
- jstack可以定位到线程堆栈
java命令--jstack 工具 JVM调优之jstack找出最耗cpu的线程并定位代码 jstack可以定位到线程堆栈,根据堆栈信息我们
- [UE4]OnComponentBeginOverlap.AddDynamic 的编译错误
以 Character 类为例,假设有 PacManCharacter 派生自 Character类首先在 PacManCharacter.h 头文件中添加碰撞函数的声明: OnCollision 为 ...
- 取得 Ajax 返回参数
ajax 函数,p1 为正常参数 function ExecWebFunction(callback,p1) { $.ajax({ type: "POST", contentTyp ...
- linux进程与线程的区别【转】
知乎上总结: "linux使用的1:1的线程模型,在内核中是不区分线程和进程的,都是可运行的任务而已.fork调用clone(最少的共享),pthread_create也是调用clone(最 ...
- 【C++11新特性】 - 空间配置allocator类
原文链接: http://blog.csdn.net/Xiejingfa/article/details/50955295 今天我们来讲讲C++的allocator类. C++提供了new和delet ...