Data.Text
和Data.Vector.Unboxed Char
在内部的工作方式有何不同?为什么我会选择一个而不是另一个?
我一直认为Haskell将String
定义为[Char]
很酷。是否有理由对Text
和Vector Char
没有做出类似的事情?
使它们相同肯定会有一个优势......可以编写Text-y和Vector-y工具以在两个阵营中使用。想象一下Ints的绳索,或者扑克牌上的Regexes。
当然,我理解可能有历史原因,而且我理解大多数现有的图书馆使用的是Data.Text
,而不是Vector Char
,因此有很多实际的理由支持其他图书馆。但我更感兴趣的是了解抽象的品质,而不是我们碰巧在当前的状态......如果整个事情明天被重写,那么统一两者会更好吗?
编辑,提供更多信息 -
将内容放入视角 -
根据此页面http://www.haskell.org/haskellwiki/GHC/Memory_Footprint,GHC在程序中为每个字符使用16个字节!
Data.Text不是O(1)index'able,它是O(n)。
Ropes(文本周围的二叉树)也可以包含字符串....它们具有更好的索引/插入/删除复杂性,尽管取决于节点的数量和树的平衡,索引可以关闭文本。
这是我从中得到的 -
Text
和Vector Char
内部不同......
如果您不关心表现,请使用字符串。
如果性能很重要,则默认使用文字。
如果需要快速索引字符,并且您不介意大量内存开销(最多16倍),请使用Vector Char。
如果要插入/删除大量数据,请使用Ropes。
答案 0 :(得分:24)
将Text
视为字符列表是一个相当糟糕的主意。 Text
旨在被视为不透明的,用户可读的Unicode文本blob。字符边界可以根据编码,区域设置,语言,月份的时间,月亮的阶段,由盲目的参与者执行的硬币翻转以及委内瑞拉国家鸟类的迁移模式来定义。排序,上装,倒车等也会发生同样的情况。
这是一个很长的路要说Text
是一种代表人类语言的抽象类型,并且远远不能像其实现那样表现得不同,不管是ByteString
,一个Vector UTF16CodePoint
,或者完全独特的东西(在这种情况下)。
为了澄清这种区别,请注意,我们无法保证unpack . pack
见证isomorphism
,从Text
转换为ByteString
的首选方法是{{1}并且是部分的,并且有一个完整的插件模块text-icu
散布着处理人类语言字符串的复杂方法。
如果您正在处理人类语言字符串,则绝对应该使用Data.Text.Encoding
。您也应该非常小心地小心对待它,因为人类语言字符串不易于计算机处理。如果您的字符串更好地被认为是一个机器字符串,您可能应该使用Text
。
ByteString
的教学优势很高,但实际优势很低。
答案 1 :(得分:8)
为了补充J. Abrahamson所说的,与单一逻辑unicode代码点相反,它也值得区分迭代符文(粗略地逐个字符,但实际上也可能是表意文字)。有时您需要知道您是否正在查看已被前一个代码点“修饰”的代码点。
对于后者,您必须区分独立的代码点(如字母,表意文字)和修改后面文本的代码点(从右到左的代码点,变音符号等) )。
良好实现的unicode库通常会抽象出这些细节,让你以一种或多或少的逐字符方式处理文本,但是你必须放弃以ASCII为思考的某些假设。
字节不是字符。文本的逻辑单元不一定是“字符”。并非每个代码点都是独立的,有些装饰/注释下面的代码点甚至是字节流的其余部分,直到无效(从右到左)。
Unicode很难。没有一种真正的编码能够消除封装人类语言固有变化的难度。尽管如此,Data.Text做得相当不错。
总结:
处理方法是:
类型是:
String(又名[Char]) - 范围有限。最适合用于教授Haskell或传统用例。
文字 - 处理“人类”文字的首选方式。
字节串 - 用于字节流,原始数据,二进制等。