虽然Haskell社区的一般意见似乎是使用Text
而不是String
总是更好,但大多数维护库的API仍为String
- 导向混淆了我的地狱。另一方面,有notable projects,将String
视为完全错误,并提供Prelude
所有以String
为导向的函数实例替换为Text
}} - 对应
那么有没有理由让人们继续编写面向String
的API,除了向后兼容的标准Prelude-compatibility和“switch-making intertia”?
与Text
相比,String
是否还有其他任何弊端?
特别是,我对此感兴趣,因为我正在设计一个库,并试图决定使用哪种类型来表达错误消息。
答案 0 :(得分:25)
我不合格的猜测是,大多数库编写者不希望添加超过必要的依赖项。由于字符串是字面上每个Haskell发行版的一部分(它是语言标准的一部分!),如果你使用字符串并且不要求你的用户从hackage中整理文本发行版,那么它会更容易被采用。
这是你必须忍受的那些“设计错误”之一,除非你能说服大多数社区过夜。只要看看让Applicative成为Monad的超类需要多长时间 - 一个相对较小但很想要的改变 - 并想象用文本替换所有String的东西需要多长时间。
要回答您更具体的问题:除非您通过使用文本获得明显的性能优势,否则我将使用String。错误消息通常是相当小的一次性事情,因此使用String不应该是一个大问题。
另一方面,如果你是那种回避实用主义理想主义的意识形态纯粹主义者,那么请选择Text。
*我把设计错误放在了恐慌引号中,因为作为chars列表的字符串是一个简洁的属性,使得它们易于推理并与其他现有的列表操作函数集成。
答案 1 :(得分:22)
如果您的API的目标是处理大量面向字符的数据和/或各种编码,那么您的API应使用文字。
如果您的API主要用于处理小型一次性字符串,那么使用内置的字符串类型应该没问题。
对大量文本使用字符串将使使用API的应用程序消耗更多内存。使用外部编码可能会严重影响使用情况,具体取决于API的工作方式。
字符串非常昂贵(至少5N个字,其中N是字符串中Char的数量)。字是与处理器体系结构相同的位数(例如32位或64位): http://blog.johantibell.com/2011/06/memory-footprints-of-some-common-data.html
答案 2 :(得分:5)
在小型项目中使用[Char]至少有三个理由。
[Char]
不依赖任何神秘的工作人员,如外国指针,原始内存,原始数组等,可能在不同的平台上以不同的方式工作,甚至完全不可用
[Char]
是haskell中的通用法语。至少有三个有效的'处理haskell中的unicode数据的方法:utf8-bytestring
,Data.Text.Text
和Data.Vector.Unboxed.Vector Char
,每个都需要处理额外的包。
使用[Char]
获得[]
monad的所有权限,包括许多特定功能(替代字符串包确实尝试帮助它,但仍然)
就个人而言,我认为 utf16 基于Data.Text
是haskell社区最值得怀疑的问题之一,因为 utf16 结合了 utf8的缺陷和 utf32 编码,但没有任何好处。
答案 3 :(得分:3)
我认为没有一个技术原因可以保留String。 我可以看到几个它可以去。
总的来说,我首先要说的是,在Text / String的情况下,只有一个最佳解决方案:
字符串表现不好,大家都同意
文字不难使用。 String上常用的所有函数都可以在Text上使用,还有一些在字符串(替换,填充,编码)上下文中有用的函数
有两个解决方案会产生不必要的复杂性,除非所有基本函数都是多态的。证明:有SO questions on the subject of automatic conversions。所以 是个问题。
因此,一个解决方案不如两个解决方案复杂,而String的缺点将最终消失。越快越好!
答案 4 :(得分:3)
我想知道Data.Text是否总是比Data.String ???
更有效 例如, let foo = "foo" ++ bigchunk
bar = "bar" ++ bigchunk
对于字符串来说比对严格文本更有效。
与效率无关的其他问题是模式匹配(明显的代码)和懒惰(在字符串中可预测的每个字符,在某种程度上实现依赖于惰性文本)。
文本显然适用于静态字符序列和就地修改。对于其他形式的结构编辑,Data.String可能有优势。