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 ...
随机推荐
- java 多线程之:wait()、notify()、notifyAll()等方法
wait().notify().notifyAll()等方法介绍: 在Object.java中,定义了wait(), notify()和notifyAll()等接口.wait()的作用是让当前线程进入 ...
- js 坐标兼容性
不同浏览器对坐标属性的支持:
- FPGA远程更新之限制条件
FPGA可重配置带来了很高的灵活性,所以基于FPGA的设计/产品往往也会有后期更新/升级的需求.同时,需要更新/升级的FPGA板卡由于物理条件的限制,可能无法现场升级.比如: 1.FPGA板卡部署在异 ...
- bzoj 3413: 匹配
Description Input 第一行包含一个整数n(≤100000). 第二行是长度为n的由0到9组成的字符串. 第三行是一个整数m. 接下来m≤5·10^4行,第i行是一个由0到9组成的字符串 ...
- word2vec剖析,资料整理备存
声明:word2vec剖析,资料整理备存,以下资料均为转载,膜拜大神,仅作学术交流之用. word2vec是google最新发布的深度学习工具,它利用神经网络将单词映射到低维连续实数空间,又称为单词嵌 ...
- [UE4]运行时创建Actor
- mysql存储过程中遍历数组字符串的两种方式
第一种:多次使用substring_index()的方法 DELIMITER $$ DROP PROCEDURE IF EXISTS `array`$$ CREATE PROCEDURE `arra ...
- 给iOS开发新手送点福利,简述UITableView的属性和用法
UITableView UITableView内置了两种样式:UITableViewStylePlain,UITableViewStyleGrouped <UITableViewDataSo ...
- 关于oracle数据库压力测试
今天接到需求,需要对oracle数据库进行压力测试,就这几个字的需求. 然后查看了以下软件: 1.Benchmark Factory是一款专业的服务器性能测试工具,专为数据库测试和可扩展性测量而设计, ...
- Ubuntu下mysql的卸载重装
注:该方法是彻底删除ubuntu下面的文件,然后重新安装,更新root密码,所以mysql原数据会被删掉,所以一定一定要记得备份!!!!!!!! 转自:http://blog.csdn.net/chu ...