安装 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. jquery禁止复制、禁用右键、文本选择功能、复制按键

    本文章介绍的jquery禁用右键.文本选择功能.复制按键的实现它可以兼容浏览器有IE.firefox.谷歌浏览器,各位朋友可参考.IE浏览器是指以IE为核心的浏览器也支持,有360,QQ等 代码如下: ...

  2. 使用JMeter代理服务器录制APP脚本

    重点:证书的安装,需要将Jmeter安装目录下证书传送到手机,使用手机安装(不要用QQ传送给手机,手机提示无法安装,可使用网盘方式传送,可成功安装证书) (出现该错误时,需安装证书) 简单的配置教程如 ...

  3. SQL 实践和技巧 <2>

    转自   http://i.cnblogs.com/EditPosts.aspx?opt=1 几个小技巧   (1)||的使用: select ‘(‘||phone[1,3]||’)’phone[5, ...

  4. LwIP:处理链路状态改变

    [文/告别年代   Email:byeyear@hotmail.com] 重大修订记录 ----------------------------------------- 2016.11.03 感谢@ ...

  5. 去除adb传输中的^M

    学习sed过程中,在文本中每行追加内容,发现使用adb会在行末追加一个看不到^M. 场景一:adb保存到文件 adb shell ps|head -n 10 > text.txt,使用sed进行 ...

  6. Linux下的压缩(zip)解压(unzip)缩命令

      .zip命令 zip -r myfile.zip ./* 将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件. 2.unzip命令 unzip -o ...

  7. 阿里云启用IPV6

    ping过别人的IPv6网址之后,可以确定,局域网是不支持IPv6的.所以要使用隧道技术建立两台机器之间的IPv6连接 1.发现测试用服务器上没有IPv6地址.所以测试服务器的内核应该是没有IPv6模 ...

  8. git clone的时候filename too long解决办法

    在git bash中,运行下列命令: git config --global core.longpaths true

  9. solr .Net端(SolrNet)

    首先 引用SolrNet.dll Microsoft.Practices.ServiceLocation HttpWebAdapters 也可以用.net IDe 中的 nuget下载 solrnet ...

  10. Elasticsearch 全文搜索和keyword search字段的mapping定义

    在ES5.0之前我们对于需要keyword search的字段都是这样定义的: { "field name":{ "type": "string&qu ...