文本或Bytestring

文本或Bytestring,string,haskell,text,String,Haskell,Text,你好 我现在最讨厌Haskell的一件事是处理string的包的数量 首先,我使用了原生Haskell[Char]字符串,但当我尝试开始使用hackage库时,却完全迷失在无休止的转换中。每个包似乎都使用不同的字符串实现,有些采用自己手工制作的东西 接下来我用Data.Textstrings和OverloadedStrings扩展重写了我的代码,我选择了Text,因为它有更广泛的函数集,但似乎许多项目更喜欢ByteString 有人可以简单地解释为什么要使用其中一种 PS:btw如何通过Test

你好

我现在最讨厌Haskell的一件事是处理string的包的数量

首先,我使用了原生Haskell
[Char]
字符串,但当我尝试开始使用hackage库时,却完全迷失在无休止的转换中。每个包似乎都使用不同的字符串实现,有些采用自己手工制作的东西

接下来我用
Data.Text
strings和
OverloadedStrings
扩展重写了我的代码,我选择了
Text
,因为它有更广泛的函数集,但似乎许多项目更喜欢
ByteString

有人可以简单地解释为什么要使用其中一种

PS:btw如何通过TestRing将
文本
转换为

无法匹配预期的类型 Data.ByteString.Lazy.Internal.ByteString 针对推断类型文本 预期类型:IO Data.ByteString.Lazy.Internal.ByteString 推断类型:IO文本

我尝试了
Data.Text.Encoding
中的
encodeUtf8
,但没有成功:

无法匹配预期的类型 Data.ByteString.Lazy.Internal.ByteString 针对推断类型Data.ByteString.Internal.ByteString

UPD:

感谢您的回复,Chunks Goods看起来很不错,但我对结果有些震惊,我的原始函数如下所示:

htmlToItems :: Text -> [Item]
htmlToItems =
    getItems . parseTags . convertFuzzy Discard "CP1251" "UTF8"
现在变成了:

htmlToItems :: Text -> [Item]
htmlToItems =
    getItems . parseTags . fromLazyBS . convertFuzzy Discard "CP1251" "UTF8" . toLazyBS
    where
      toLazyBS t = fromChunks [encodeUtf8 t]
      fromLazyBS t = decodeUtf8 $ intercalate "" $ toChunks t

是的,这个函数不起作用是因为它是错误的,如果我们向它提供
文本
,那么我们确信这个文本是正确编码的,可以使用,转换它是愚蠢的事情,但是这种详细的转换仍然必须在
htmltoItems

ByteStrings
之外的某个地方进行,它主要对二进制数据有用,但如果您只需要ASCII字符集,它也是处理文本的一种有效方法。如果需要处理unicode字符串,则需要使用
Text
。但是,我必须强调,两者都不能替代另一种,它们通常用于不同的用途:虽然
文本
表示纯unicode,但无论何时(例如,通过套接字或文件传输文本),您仍然需要对二进制
ByteString
表示进行编码

这是一篇关于unicode基础知识的好文章,它很好地解释了unicode代码点(
Text
)和编码的二进制字节(
ByteString
)之间的关系:


您可以使用该模块在两种数据类型之间进行转换,或者如果您使用的是惰性变量(正如您根据错误消息所做的那样)。

您肯定希望使用Data.Text作为文本数据

encodeUtf8
是一种方法。此错误:

无法匹配预期的类型Data.ByteString.Lazy.Internal.ByteString 针对推断类型Data.ByteString.Internal.ByteString

这意味着您正在为需要惰性bytestring的代码提供严格的bytestring。使用
fromChunks
功能可以轻松进行转换:

Data.ByteString.Lazy.fromChunks :: [Data.ByteString.Internal.ByteString] -> ByteString
因此,您所需要做的就是将函数
fromChunks[myStrictByteString]
添加到需要lazy bytestring的任何位置

另一种方式的转换可以通过双函数
toChunks
完成,该函数接受一个lazy bytestring并给出一个严格块列表


您可能想询问一些软件包的维护人员,他们是否能够提供文本接口,而不是bytestring接口,或者作为bytestring接口的补充。

使用
Data.String.Conversions中的单个函数
cs

它将允许您在
字符串
ByteString
文本
(以及
ByteString.Lazy
文本.Lazy
)之间进行转换,具体取决于输入和预期的类型

您仍然需要调用它,但不再需要担心各自的类型


有关用法示例,请参见。

关于它的价值,我发现这两个助手函数非常有用:

将限定数据.ByteString.Char8作为BS导入
导入符合条件的数据。文本为T
--|文本到ByteString
tbs::T.Text->BS.ByteString
tbs=BS.pack。拆包
--|通过测试环到文本
bst::BS.ByteString->T.Text
bst=T.pack。开箱
例如:

foo::[BS.ByteString]
foo=[“你好”,“世界”]
条::[T.Text]
bar=bst-foo
baz::[BS.ByteString]
baz=tbs棒

Haskell的朋友们,请使用统一的字符串:)@Ankur:
Text
正在成为事实上的文本实现。字符串仍然存在,原因很简单,但对于严重的文本操作,您应该使用文本。@ivanm:如果所有基于bytestring的遗留库都能转换,那就好了@ivanm事实上,文本不可用,我现在使用的库很少(Database.MongoDB,Text.Iconv),而且没有一个库尊重
文本
,手动进行所有转换感觉不正常。您最初是如何以及从何处获得文本的?您遇到问题的原因是您永远不必在不同的编码之间转换文本。首先应该使用正确的编码对文本数据进行解码,然后使用
htmlToItems=getItems。parseTags
这里是另一面,因为我所有的字符串都已经很严格:无法将预期的类型
文本与推断的类型数据相匹配。Text.Lazy.Internal.Text
所以我找到了fromChunks作为文本,好吧,但最终结果仍然很难看。请不要将ByTestRing用于“文本”数据,即使您需要的只是ASCII。文本用于文本数据,ByteString用于压缩数据结构。如果我们都同意什么类型应该在语义上表示,那么我们就不会对使用哪种类型产生太多的混淆,最终也会减少类型之间的转换。”无论何时,当您(例如,通过套接字或