Haskell's Data.Text:用作文本编辑器的基础好吗?

Haskell's Data.Text: Good to use as basis for text editor?

当命令式程序员很久了,时不时回顾一下Haskell,多玩一点,多学一点。

在思考一个可能的项目时出现了一个问题:

如何使用将数据视为不可变的语言来实现我明确想要更改的数据?

一个具体的例子是文本编辑器编辑的文本。 Data.Text 是可用的,但它说像在文本末尾附加一个字符这样的事情涉及复制整个文本。由于类似的事情,我想知道 Data.Text 是否是用于实现旨在更改的文本的适当结构。

是否有解决此类问题的通用思路?

多年来,我用 C# 编写了两个文本机制的实现。一个使用了 256 个(或 512,我忘记了,已经有一段时间了)字符块的链接列表,类似于 Sam 文本编辑器中描述的内容。另一个是 Oberon 系统中由 Niklaus Wirth(他从别人那里得到的)设计的略微修改版本,其中文本由两个文件(一个用于原始文本,另一个用于新输入的数据)和一个链接文件实现用于 assemble 和编辑文本的片段列表。我使用了两个 .NET StringBuilder 而不是文件,只附加到它们,并且整个事情比仅使用 StringBuilders 作为文本本身表现得更好。

注意: 我对懒惰、严格、尾递归、thunks 有合理的工作知识。 Fusion 对我来说不太清楚,但我已经阅读了一些。

我在 SQL 方面有很多经验,所以我对编译器执行我不完全理解的事情没有问题,但在那种语言中我知道如何更好地概念化问题比我在 Hasell 做的还要多。

Haskell 中编辑器实现的标准参考可能是 Yi editor。它的作者写了一些论文讨论这个,例如:

  • “易:Haskell Haskell 的编辑” (DOI, PDF)

  • “惰性函数式增量解析”(DOI, PDF)

像许多文本编辑器一样,Yi 使用 rope as the representation of text buffers. Specifically, it’s a purely functional rope called Yi.Rope.YiString containing chunks of Text, defined as a specialisation of Data.FingerTree.FingerTree, the same data structure underlying Data.Sequence.Seq。还有进一步的优化,例如将索引缓存到文本中和在缓冲区上批量操作,但核心只是 Unicode 文本块的持久树。

使用持久数据结构会产生对数时间成本,但会使某些功能(例如缓存历史记录和增量计算)更容易正确实现。