2013-10-26 136 views
54

虽然哈斯克尔社会的普遍看法似乎是,它总是更好地使用Text代替String,事实上,大部分维持图书馆的仍是API是String取向混淆了地狱的我。另一方面,存在notable projects,它们将String视为一个错误,并提供Prelude所有面向String函数的实例都被它们的Text计数器替换。Data.Text VS字符串

那么除了向后兼容的标准Prelude兼容性和“开关制造间接”以外,还有什么原因让人们继续编写String-oriented API? 与String相比,Text有没有其他缺点?

特别是,我对此感兴趣,因为我正在设计一个库并试图决定使用哪种类型来表示错误消息。

+0

支持两者有多难? –

+0

字符串很容易使用,但文本效率很高。 我说,效率是一个编译器问题,因为它的编译器工作要优化。让程序员写一个更快的库只是意味着编译器不够好。 (可悲的是,我们没有很好的编译器) – Vektorweg

+6

@Vektorweg我会争辩。由于'String'只是一个Char列表的别名,因此它与'Text'的单片数据具有不同的性能特征是很自然的。这两种类型完全没有编译器的关注,因为它们不是原始的,并且在库中定义。 –

回答

19

我的不合格猜测是,大多数库编写者不想添加更多的依赖关系。由于字符串是字面上每一个Haskell发行版的一部分(它是语言标准的一部分!),所以如果使用字符串并且不要求用户从发行版中挑选文本发行版,那么获得采用就会容易得多。

这是您必须忍受的那些“设计错误”之一,除非您能说服大部分社区转换过夜。看看Applicative是Monad的一个超类 - 需要多长时间才能做出改变 - 并想象用Text代替所有String事物需要多长时间。


要回答你的更具体的问题:我会去的字符串,除非你用文本明显的性能优势。错误消息通常是相当小的一次性事情,所以使用String不应该是一个大问题。另一方面,如果你是那种避开理想主义的实用主义的思想纯粹主义者,那就用文本吧。


*我把设计失误恐慌引号是因为字符串作为一个列表的-字符是一个整洁的属性,使得它们很容易推理,并与其他现有的列表,操作功能集成。

+3

这不仅仅是一种纯粹的狂热,它只是为了更好地转换(如果它真的是一个),而不是次优方法的停滞。好的,所以你确认使用Text基本上没有缺点? –

+3

@NikitaVolkov如果你想贡献一个开关,我认为你可以通过参与更新标准和游说/转换现有库的过程来做出更大的改变。除了您可以想到的几乎没有什么缺点,例如采用率和想要在第一个字母上匹配模式的人或使用Data.List等的地图。 – kqr

+4

这可能不再那么重要了,因为Data.Text现在已经很多了,并且与GHC(我假设大多数人使用这些日子)​​一起开箱即用。 – Profpatsch

16

如果您的API旨在处理大量面向字符的数据和/或各种编码,那么您的API应使用文本

如果您的API主要用于处理小的一次性字符串,那么使用内置的字符串类型应该没问题。

使用字符串对于大量文本会使应用程序使用您的API消耗更多的内存。根据API的工作原理,将它与外部编码一起使用可能会严重使其复杂化。

字符串非常昂贵(至少5N个字,其中N是字符串中的字符数)。字是相同的位数的处理器体系结构的(例如32位或64位): http://blog.johantibell.com/2011/06/memory-footprints-of-some-common-data.html

+10

我不认为ASCII与它有任何关系:String和Text同样支持Unicode,将实际编码推到抽象层次下。在这两种情况下,您只需在程序的边界处担心它。 Unicode支持不是在两者之间进行选择的好标准。 –

+4

你把'String'和'ByteString'混合在一起,关于ASCII。 –

+1

@TikhonJelvis不存在这样的问题:字符串中的一个“字符”只能是Unicode字符的一部分,而不是单个Unicode字符?这不会造成混淆吗? Data.Text能解决这个问题吗? –

5

至少有三个原因使用[字符]在小的项目。

  1. [Char]不依赖于任何神秘的员工,喜欢外国的指针,原始内存,生阵列等,可能不同的工作在不同的平台,甚至是无法完全

  2. [Char]是通用弗兰卡在哈斯克尔。在haskell中至少有三种'高效'的方式来处理unicode数据:utf8-bytestring,Data.Text.TextData.Vector.Unboxed.Vector Char,每个都需要处理额外的包。

  3. 使用[Char]一个获得访问[]单子的所有电源,包括许多特殊功能(替代串包会尽力帮助,但仍然)

我个人认为UTF-16 - 基于Data.Text haskell社区最可疑desicions之一,因为utf16结合缺陷的两个utf8utf32编码,而没有的好处。

+1

你可以提供更多的信息,为什么你认为utf16是劣等的?不一定作为这个答案的一部分,但也许是一篇详细描述你的立场的文章。 – Wizek

+1

@Wizek--这是一个相当普遍的观点。请参阅http://programmers.stackexchange.com/questions/102205/should-utf-16-be-considered-harmful。 – Jules

3

我不认为有一个字符串保持单一技术原因。 我可以看到它的几个去。

总的来说,我会首先认为,在文本/字符串的情况下,只有一个最好的解决办法:

  • 字符串的表演是坏,每个人都对

  • 文字同意并不难用。上的字符串中常用的所有功能,可以在文本,加在串

  • 具有两个解决方案产生不必要的,除非所有基函数是由多晶型的复杂性的上下文中(取代,填充,编码)一些有用的多。证明:有SO questions on the subject of automatic conversions。所以这的一个问题。

所以一个解决方案比两个解决方案简单一些,而且字符串的缺点最终会使它消失。越快越好!

+0

这不是那么简单,不。这里有一些非常重要的字符串处理代码,它们是围绕'String'设计的,并且不能很好地处理'Text'。 – dfeuer

+0

@dfeuer我会对指针非常感兴趣 - 我非常缺乏这些案例的第一手经验。 – Titou

3

我不知道Data.Text总是比Data.String更有效吗?

“cons”例如对于字符串是O(1),对于文本是O(n)。 Append对于Strings来说是O(n),对于严格Text来说是O(n + m)。同样地,

let foo = "foo" ++ bigchunk 
     bar = "bar" ++ bigchunk 

是更有效的空间弦乐比严格文本。

没有涉及到效率

另一个问题是模式匹配(明晰代码)和lazyness(可预测的每字符的字符串,在某种程度上取决于执行的懒惰文本)。

文字的都是静态的字符序列和就地修改显然不错。对于其他形式的结构编辑,Data.String可能有优势。