2013-10-26 58 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可能有優勢。