Haskell语言学习笔记(36)Data.List.Zipper
ListZipper 模块
$ cabal install ListZipper
Installed ListZipper-1.2.0.2
Prelude> :m +Data.List.Zipper
Prelude Data.List.Zipper>
Zipper 和 ListZipper
Zipper 是一种带焦点(focus,也称游标, cursor)的数据结构。使用 Zipper 可以很方便的在底层数据结构中进行遍历,更新,插入,删除等操作。
ListZipper 是建立在 List 这种数据结构上的 Zipper,可以理解为带焦点(游标)的List。
ListZipper 函数示例
Prelude Data.List.Zipper> z = fromList [3,4,5]
Prelude Data.List.Zipper> z
Zip [] [3,4,5]
Prelude Data.List.Zipper> replace 6 z
Zip [] [6,4,5]
Prelude Data.List.Zipper> toList z
[3,4,5]
Prelude Data.List.Zipper> emptyp z
False
Prelude Data.List.Zipper> beginp z
True
Prelude Data.List.Zipper> end z
Zip [5,4,3] []
Prelude Data.List.Zipper> cursor z
3
Prelude Data.List.Zipper Data.Function> z & right & right
Zip [4,3] [5]
Prelude Data.List.Zipper Data.Function> z & insert 6
Zip [] [6,3,4,5]
Prelude Data.List.Zipper Data.Function> z & push 6
Zip [6] [3,4,5]
Prelude Data.List.Zipper Data.Function> z & right & pop
Zip [] [4,5]
Prelude Data.List.Zipper Data.Function> z & right & foldrz (\z b -> cursor z + b) 0
9
Prelude Data.List.Zipper Data.Function> z & right & foldlz (\b z -> cursor z + b) 0
9
Prelude Data.List.Zipper> extractz z
3
Prelude Data.List.Zipper> duplicatez z
Zip [] [Zip [] [3,4,5],Zip [3] [4,5],Zip [4,3] [5]]
Prelude Data.List.Zipper> extendz (\z -> show (cursor z)) z
Zip [] ["3","4","5"]
import Control.Monad.State
import Data.List.Zipper
f :: State (Zipper Int) [Int]
f = do
modify right -- [3],[4,5]
modify $ replace 6 -- [3],[6,5]
modify $ insert 7 -- [3],[7,6,5]
gets toList -- [3,7,6,5]
main = print . evalState f $ fromList [3,4,5]
理解 ListZipper
data Zipper a = Zip ![a] ![a] deriving (Eq,Show)
fromList :: [a] -> Zipper a
fromList as = Zip [] as
toList :: Zipper a -> [a]
toList (Zip ls rs) = reverse ls ++ rs
left :: Zipper a -> Zipper a
left (Zip (a:ls) rs) = Zip ls (a:rs)
left z = z
right :: Zipper a -> Zipper a
right (Zip ls (a:rs)) = Zip (a:ls) rs
right z = z
insert :: a -> Zipper a -> Zipper a
insert a (Zip ls rs) = Zip ls (a:rs)
delete :: Zipper a -> Zipper a
delete (Zip ls (_:rs)) = Zip ls rs
delete z = z
push :: a -> Zipper a -> Zipper a
push a (Zip ls rs) = Zip (a:ls) rs
pop :: Zipper a -> Zipper a
pop (Zip (_:ls) rs) = Zip ls rs
pop z = z
replace :: a -> Zipper a -> Zipper a
replace a (Zip ls (_:rs)) = Zip ls (a:rs)
replace _ z = z
- data Zipper a = Zip ![a] ![a] deriving (Eq,Show)
ListZipper 是建立在List 上的数据结构,它包含两个List,其中第二个List的第一个元素是当前的焦点。
也就是说左边的 List 包含焦点之前的元素,而右边的 List 则包含焦点及其之后的元素。 - fromList as = Zip [] as
fromList 将 List 参数 as 转换成 Zipper,当前焦点在as的第一个元素。 - toList (Zip ls rs) = reverse ls ++ rs
toList 将 Zipper 转换成 List。 - left (Zip (a:ls) rs) = Zip ls (a:rs)
left 函数将当前焦点左移一个元素。即左边 List 的第一个元素被移至右边 List 的最前端。 - right (Zip ls (a:rs)) = Zip (a:ls) rs
right 函数将当前焦点右移一个元素。即右边 List 的第一个元素被移至左边 List 的最前端。 - insert a (Zip ls rs) = Zip ls (a:rs)
insert 函数在当前焦点处插入新元素。即在右边 List 的最前端插入新元素。 - delete (Zip ls (_:rs)) = Zip ls rs
delete 函数移除处位于焦点处的元素。即右边 List 的第一个元素被移除。 - push a (Zip ls rs) = Zip (a:ls) rs
push 函数在当前焦点之前插入新元素。即在左边 List 的最前端插入新元素。 - pop (Zip (_:ls) rs) = Zip ls rs
pop 函数移除位于焦点之前的一个元素。即左边 List 的第一个元素被移除。 - replace a (Zip ls (_:rs)) = Zip ls (a:rs)
replace 函数替换当前焦点处的元素。即右边 List 的第一个元素被替换。
Haskell语言学习笔记(36)Data.List.Zipper的更多相关文章
- Haskell语言学习笔记(88)语言扩展(1)
ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...
- Haskell语言学习笔记(69)Yesod
Yesod Yesod 是一个使用 Haskell 语言的 Web 框架. 安装 Yesod 首先更新 Haskell Platform 到最新版 (Yesod 依赖的库非常多,版本不一致的话很容易安 ...
- Haskell语言学习笔记(20)IORef, STRef
IORef 一个在IO monad中使用变量的类型. 函数 参数 功能 newIORef 值 新建带初值的引用 readIORef 引用 读取引用的值 writeIORef 引用和值 设置引用的值 m ...
- Haskell语言学习笔记(79)lambda演算
lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...
- Haskell语言学习笔记(39)Category
Category class Category cat where id :: cat a a (.) :: cat b c -> cat a b -> cat a c instance ...
- Haskell语言学习笔记(28)Data.Map
Map Prelude> import Data.Map as Map Prelude Map> :set -XOverloadedLists Prelude Map> Overlo ...
- Haskell语言学习笔记(93)Data.Text
Data.Text.Read Prelude> :set -XOverloadedStrings Prelude> :m +Data.Text.Read Prelude Data.Text ...
- Haskell语言学习笔记(81)Data.Typeable
Data.Typeable 利用 Data.Typeable,可以打印动态类型信息. class Typeable (a :: k) where typeRep# :: TypeRep a typeR ...
- Haskell语言学习笔记(77)Data.HashSet
安装 unordered-containers $ cabal install unordered-containers Installed unordered-containers-0.2.9.0 ...
随机推荐
- postman的Testing examples(测试脚本示例)
测试代码会在发送request并且接收到responses后执行. 1.设置环境变量 postman.setEnvironmentVariable("key", "val ...
- ASP.NET实现Cookie功能的三个基本操作(写入,读取,删除)
说正事 简而言之,在Cookie的时候有三个过程,分别是“写入,读取,删除”.任何伟大之作都是有基本的东西构成的,而Cookie的运用也不例外. 写入: 1 //创建一个HttpCookie对象 ...
- Django安装与介绍
安装 Django是以Python为语言环境的,所以要先确保计算机上已经安装了Python. Linux ubuntu: sudo pip install Django==1.11.7 安装中指定了版 ...
- 【Spring学习笔记-MVC-10】Spring MVC之数据校验
作者:ssslinppp 1.准备 这里我们采用Hibernate-validator来进行验证,Hibernate-validator实现了JSR-303验证框架支持注解风格的验证.首先 ...
- 第5章 pandas入门
pandas是专门为处理表格和混杂数据设计的,NumPy更适合处理统一的数值数组数据. pandas的数据结构: Series:Series是一种类似于一维数组的对象,它由一组数据(各种NumPy数据 ...
- bzoj1293 生日礼物
Description 小西有一条很长的彩带,彩带上挂着各式各样的彩珠.已知彩珠有N个,分为K种.简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置).某些坐标上可以没有彩珠,但多个彩 ...
- linux 查看文件夹下的文件个数(当前目录的文件数)//包含子目录
ls -l |grep "^-"|wc -l //验证了redhat好用 或 find ./company -type f | wc -l 查看某文件夹下文件的个数,包括子文件 ...
- tomcat 乱码问题
页面提交都是utf8编码进后台,但是后台入库有些中文数据是正常,有些是乱码,可以完全排除数据库层面的问题 比较一下正常和异常的http请求,一个是Get,一个是Post, 原因就找到了 tomcat4 ...
- javascript创建对象之稳妥构造函数模式(七)
所谓稳妥对象,指的是没有公共属性,而且其方法也不引用this的对象.稳妥对象最适合在一些安全的环境中(禁止使用this和new)或者在防止数据被其他应用程序改动时. 稳妥构造函数模式有2个特点:1.新 ...
- Ubuntu14.04下hadoop-2.6.0单机配置和伪分布式配置
需要重新编译的教程:http://blog.csdn.net/ggz631047367/article/details/42460589 在Ubuntu下创建hadoop用户组和用户 hadoop的管 ...