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. MapReduce-寻找三角形

    在图中,如何判断三角形?三角形在很多场景都有应用,比如社交网络中确定人和人之间的关系. 那么如果通过代码逻辑来实现呢?在数据结构之图中,区分三联体(有一端没有关联关系的三角形)和三角形是关键:两者之间 ...

  2. linux I2C_client产生方法一

    \arch\arm\mach-omap2/board-am335xevm.c static struct i2c_board_info am335x_i2c2_boardinfo[] = { {  I ...

  3. 嵌入式QT程序的汉字显示

    因底层服务程序全是GBK格式的,所以QT程序要全部更改编码方式. 1.QT程序编码更改 creator->edit->更改编码方式GBK main程序中做如下修改,并注意语句次序 int ...

  4. Tomcat 去除项目名称

    再tomcat的conf下server.xml  里, 再<host>...</host>的标签之间添加 <Context path="" docBa ...

  5. R(7): data.table

    这个包让你可以更快地完成数据集的数据处理工作.放弃选取行或列子集的传统方法,用这个包进行数据处理.用最少的代码,你可以做最多的事.相比使用data.frame,data.table可以帮助你减少运算时 ...

  6. 【python】网络编程-SocketServer 实现客户端与服务器间非阻塞通信

    利用SocketServer模块来实现网络客户端与服务器并发连接非阻塞通信.首先,先了解下SocketServer模块中可供使用的类:BaseServer:包含服务器的核心功能与混合(mix-in)类 ...

  7. bisect维持已排序的序列

    如下: import bisect # 用来处理已排序的序列,用来维持已排序的序列,升序 # 基于二分查找 li = [] bisect.insort(li, 2) bisect.insort(li, ...

  8. Django 中 python manage.py makemigrations 与 python manage.py migrate

    执行 python manage.py makemigrations django根据settings.py里面的INSTALLED_APPS项设置找到对应app里的models.py,应用里面创建的 ...

  9. jQuery控制网页字体大小和肤色

    在一些网站上经常看到有控制网页肤色和字体大小的功能,接下来,我们将用两个例子来实现这两个功能. 网页字体大小 首先我们在网页中添加一些被控制大小的文字和字体控制的按钮. <!DOCTYPE> ...

  10. IE6 CSS高度height:100% 无效解决方法总结

    原文地址:http://www.cnblogs.com/huangyong8585/archive/2013/02/05/2893058.html   上面红色部分为 height:100%; 自动拉 ...