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 ...
随机推荐
- Servlet 串联过滤器
1. 串联Servlet过滤器的工作流程 2. 创建两个过滤器 MyFilter1和MyFilter2 1) MyFilter1 package com.example.filter; import ...
- 在ubuntu中安装luci解决iwinfo.h No such file or directory问题
问题: src/luci-bwc.c:35:20: fatal error: iwinfo.h: No such file or directorycompilation terminated.mak ...
- 【Spring学习笔记-3.1】让bean获取spring容器上下文(applicationContext.xml)
*.hl_mark_KMSmartTagPinkImg{background-color:#ffaaff;}*.hl_mark_KMSmartTagBlueImg{background-color:# ...
- zabbix 安装错误汇总
由于公司业务需要,当前zabbixserver的压力较大,需要安装一个proxy缓解压力,开始慢慢琢磨proxy的安装.这些文档网上很多,就不在多说了.只把自己遇见的错误拿出来共享下 Zabbixpr ...
- HTTP Status 500 - The absolute uri: http://java.sun.com/jsp/jstl/core cannot-报错解决方法
操作:jsp文件里面添加<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" % ...
- shell 13文件包含
同其他语言一样,shell也可以包含外部脚本.执行引用脚本可以使用source或 . 示例1 test.sh #shell #!/bin/sh echo "test.sh开始执行" ...
- servlet的讲解
https://www.ibm.com/developerworks/cn/java/j-lo-servlet/
- volotile关键字的内存可见性及重排序
在理解volotile关键字的作用之前,先粗略解释下内存可见性与指令重排序. 1. 内存可见性 Java内存模型规定,对于多个线程共享的变量,存储在主内存当中,每个线程都有自己独立的工作内存,并且线程 ...
- 如何在一个js文件中引入另外的js文件
例如想要在a.js中引用b.js.c.js和d.js document.write("<script language='javascript' src='b.js'></ ...
- 下载任意版本的Chromium
Download Chromium You can test Chrome builds or Chromium builds. Chrome builds have the most infras ...