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的更多相关文章

  1. Haskell语言学习笔记(88)语言扩展(1)

    ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...

  2. Haskell语言学习笔记(69)Yesod

    Yesod Yesod 是一个使用 Haskell 语言的 Web 框架. 安装 Yesod 首先更新 Haskell Platform 到最新版 (Yesod 依赖的库非常多,版本不一致的话很容易安 ...

  3. Haskell语言学习笔记(20)IORef, STRef

    IORef 一个在IO monad中使用变量的类型. 函数 参数 功能 newIORef 值 新建带初值的引用 readIORef 引用 读取引用的值 writeIORef 引用和值 设置引用的值 m ...

  4. Haskell语言学习笔记(79)lambda演算

    lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...

  5. Haskell语言学习笔记(39)Category

    Category class Category cat where id :: cat a a (.) :: cat b c -> cat a b -> cat a c instance ...

  6. Haskell语言学习笔记(28)Data.Map

    Map Prelude> import Data.Map as Map Prelude Map> :set -XOverloadedLists Prelude Map> Overlo ...

  7. Haskell语言学习笔记(93)Data.Text

    Data.Text.Read Prelude> :set -XOverloadedStrings Prelude> :m +Data.Text.Read Prelude Data.Text ...

  8. Haskell语言学习笔记(81)Data.Typeable

    Data.Typeable 利用 Data.Typeable,可以打印动态类型信息. class Typeable (a :: k) where typeRep# :: TypeRep a typeR ...

  9. Haskell语言学习笔记(77)Data.HashSet

    安装 unordered-containers $ cabal install unordered-containers Installed unordered-containers-0.2.9.0 ...

随机推荐

  1. Python——面向对象、绑定对象、组合

    1. 面向过程VS面向对象 (1)面向过程 核心是过程(流水线式思维),过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东西. 优点是:极大的降低了写程序的复杂 ...

  2. MongoDB配置成系统服务(Win)

    bin同级目录下创建文件夹data 进入data创建文件夹db和文件夹logs 进入logs创建文件mongo.log 以管理员权限打开cmd,进入mongo的bin目录下执行命令: mongod - ...

  3. AspectJ入门

    AOP的实现方式有两种: AOP框架在编译阶段,就对目标类进行修改,得到的class文件已经是被修改过的.生成静态的AOP代理类(生成*.class文件已经被改掉了,需要使用特定的编译器).以Aspe ...

  4. javascript讲解

    1. js介绍 js的全称 javascript     由布兰登 艾奇发明的 javascript和java是有区别的 javascript是一门前台语言,而Java 是后台语言 前台语言运行在客户 ...

  5. Windows下python 安装Mysqldb模块

    CMD执行 pip install mysql-python 报错如下: 1.如果报类似 Microsoft Visual C++ 9.0 is required < Unable to fin ...

  6. 1002 A+B for Polynomials (25 分)

    This time, you are supposed to find A+B where A and B are two polynomials. Input Specification: Each ...

  7. ORACLE V$lock视图TYPE,ID1,ID2取值的含义

    在oracle v$lock视图中,下面对type,ID1,ID2三个列的具体含义说明下: TYPE   有TM,TX两种类型,TX为行级锁,事物锁,TM锁为表级锁 TYPE ID1 ID2 TM 被 ...

  8. 基于Linux的Samba开源共享解决方案测试(三)

    在极限写场景下,对于网关的网络监控如图: 在极限写场景下,对于网关的网络监控如图: 在极限混合读写场景下,对于网关的网络监控如图: 在极限混合读写场景下,对于客户端的网络监控如图: 双NAS网关100 ...

  9. html大小写问题

    js中变量名,函数,关键字都区分大小写,如var i;和var I;是两个不同的变量. css中定义的元素名称不区分大小写的. html中,标签和标签属性统一使用小写形式,固有属性也一律使用小写,自定 ...

  10. AVL树Python实现

    # coding=utf-8 # AVL树Python实现 def get_height(node): return node.height if node else -1 def tree_mini ...