我正在尝试编写一个从字符串中删除特定元素的程序,但我使用的大多数东西(例如filter)仅适用于[Char]. 我真的只是不想打字"['h','e','l','l','o']"而不是"hello"。我意识到从技术上讲 aString只是一个幻想[Char],但我如何将它变成一个标准[Char]。另外,如果您有另一种方法来编写普通单词而不是数组格式,请告诉我。
正如已经说过的,String只是一个同义词[Char]
type String = [Char]\nRun Code Online (Sandbox Code Playgroud)\n所以两者可以互换使用。
\n特别是,与"hello" :: [Char]完全相同"hello" :: String,两者只是更优雅的书写方式[\'h\',\'e\',\'l\',\'l\',\'o\']。
也就是说,你会发现并非所有在其他语言中为 \xe2\x80\x9cString\xe2\x80\x9d 的东西String在 Haskell 中都是 a 。看,列表实现实际上效率很低,特别是对于 ASCII 字符串来说,在内存方面 \xe2\x80\x93 ,大多数语言每个字符采用 8 或 16 位,但对于 Haskell\ 的类型,每个字符String都是 64 位Char加上对下一个字符的引用,总共 128 位!
这就是为什么大多数现代 Haskell 库都避免使用String,除了像文件名这样的简短内容。(顺便说一句,
type FilePath = String\nRun Code Online (Sandbox Code Playgroud)\n所以这也是可以互换的。)
\n这些库用于一般字符串的通常是Text,这确实是一种不同的类型,更多地对应于其他语言的实现(它在底层使用 UTF-16)。
如果您想过滤该类型的值,您可以将其转换为 listy- Stringwith ,或者您可以简单地使用文本库提供的unpack专用版本。filter
在标准 Haskell 中,Text值不能定义为字符串或列表文字,您需要像pack [\'h\',\'e\',\'l\',\'l\',\'o\']. 但是,只要您打开,它们仍然可以{-# LANGUAGE OverloadedStrings #-}使用简单的字符串文字来定义:
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"\nRun Code Online (Sandbox Code Playgroud)\n通过另一个扩展,这也适用于列表语法:
\nghci> [\'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"\nRun Code Online (Sandbox Code Playgroud)\n