如何将字符串转换为字符列表?

Amb*_*ber 6 haskell

我正在尝试编写一个从字符串中删除特定元素的程序,但我使用的大多数东西(例如filter)仅适用于[Char]. 我真的只是不想打字"['h','e','l','l','o']"而不是"hello"。我意识到从技术上讲 aString只是一个幻想[Char],但我如何将它变成一个标准[Char]。另外,如果您有另一种方法来编写普通单词而不是数组格式,请告诉我。

lef*_*out 5

正如已经说过的,String只是一个同义词[Char]

\n
type String = [Char]\n
Run Code Online (Sandbox Code Playgroud)\n

所以两者可以互换使用。

\n

特别是,与"hello" :: [Char]完全相同"hello" :: String,两者只是更优雅的书写方式[\'h\',\'e\',\'l\',\'l\',\'o\']

\n

也就是说,你会发现并非所有在其他语言中为 \xe2\x80\x9cString\xe2\x80\x9d 的东西String在 Haskell 中都是 a 。看,列表实现实际上效率很低,特别是对于 ASCII 字符串来说,在内存方面 \xe2\x80\x93 ,大多数语言每个字符采用 8 或 16 位,但对于 Haskell\ 的类型,每个字符String都是 64 位Char加上对下一个字符的引用,总共 128 位!

\n

这就是为什么大多数现代 Haskell 库都避免使用String,除了像文件名这样的简短内容。(顺便说一句

\n
type FilePath = String\n
Run Code Online (Sandbox Code Playgroud)\n

所以这也是可以互换的。)

\n

这些库用于一般字符串的通常是Text,这确实是一种不同的类型,更多地对应于其他语言的实现(它在底层使用 UTF-16)。

\n

如果您想过滤该类型的值,您可以将其转换为 listy- Stringwith ,或者您可以简单地使用文本库提供的unpack专用版本。filter

\n

在标准 Haskell 中,Text值不能定义为字符串或列表文字,您需要像pack [\'h\',\'e\',\'l\',\'l\',\'o\']. 但是,只要您打开,它们仍然可以{-# LANGUAGE OverloadedStrings #-}使用简单的字符串文字来定义:

\n
ghci> :m +Data.Text\nghci> "hello" :: Text\n\n<interactive>:5:1: error:\n    \xe2\x80\xa2 Couldn\'t match expected type \xe2\x80\x98Text\xe2\x80\x99 with actual type \xe2\x80\x98[Char]\xe2\x80\x99\n    \xe2\x80\xa2 In the expression: "hello" :: Text\n      In an equation for \xe2\x80\x98it\xe2\x80\x99: it = "hello" :: Text\n\nghci> :set -XOverloadedStrings \nghci> "hello" :: Text\n"hello"\n
Run Code Online (Sandbox Code Playgroud)\n

通过另一个扩展,这也适用于列表语法:

\n
ghci> [\'h\',\'e\'] :: Text\n\n<interactive>:9:1: error:\n    \xe2\x80\xa2 Couldn\'t match expected type \xe2\x80\x98Text\xe2\x80\x99 with actual type \xe2\x80\x98[Char]\xe2\x80\x99\n    \xe2\x80\xa2 In the expression: [\'h\', \'e\'] :: Text\n      In an equation for \xe2\x80\x98it\xe2\x80\x99: it = [\'h\', \'e\'] :: Text\n\nghci> :set -XOverloadedLists \nghci> [\'h\',\'e\'] :: Text\n"he"\n
Run Code Online (Sandbox Code Playgroud)\n