【问题标题】:Haskell - how to convert [1,2,3] to "123"Haskell - 如何将 [1,2,3] 转换为“123”
【发布时间】:2015-04-21 02:42:04
【问题描述】:

如何将整数列表 [1,2,3] 转换为字符串“123”

很抱歉问了一些显而易见的问题,但我似乎无法在其他地方找到答案。

【问题讨论】:

  • 这不是一个明显的重复。我在寻找一个字符串。
  • @Akarienta 不是重复的,这里的 OP 想要创建一个字符串,正如问题中明确指出的那样,而在您链接的问题中,目标是用单个数字创建一个新的 Int,解决方案完全不同(尽管两者都可以通过折叠来实现)
  • @bheklilr 好吧,例如this one。 SO充满了这些问题,作者没有用过搜索。
  • @Akarienta 确实如此,但是当有人根本不知道要使用的功能时,它就无济于事了。这可能是concatMap show 的两个字解决方案,它只是学习API。这里解决的实际问题是学习 Prelude 中以前未知的功能。这并不是说 OP 需要调整一个更复杂的问题来满足他的需求,这仅仅是对现有解决方案的无知。是的,程序员需要学习如何阅读文档并解决类似的问题,但我敢打赌,当你第一次开始使用 Haskell 时,你并不知道 concatMap

标签: haskell


【解决方案1】:

或者,您可以使用

map (chr . (ord '0' +)) [1,2,3,4]

如果您的所有整数都是个位数(您需要从Data.Char 导入chrord)。

这是可行的,因为 String 只是 Haskell 中 [Char] 的类型同义词,所以我们所做的只是将列表中的每个 Int 映射到适当的 Char

【讨论】:

  • 另一种避免导入的方法:map ( (toEnum::Int->Char) . (fromEnum '0' +) ) [1,2,3,4]
【解决方案2】:

最好的方法是使用showconcatMap,这只是concatmap 的组合:

> concatMap show [1, 2, 3]
"123"

这也适用于多于一位的数字:

> concatMap show [10, 20, 30]
"102030"

由于type String = [Char],我们可以将其视为列表处理问题第一部分是将每个数字转换为其String表示,只需使用show即可完成。由于我们想将此应用于数字列表,因此map 是首选工具。最后,我们想将所有字符串表示(Char 表示的列表)连接成一个字符串(Char 的列表),所以concat 是合适的:

> concat $ map show [1, 2, 3]
"123"

无论何时看到concat $ map f some_list,您都可以随时使用预定义工具concatMap,因为这正是它的定义:

> concatMap show [1, 2, 3]
"123"

正如 cmets 中所指出的,您可以使用 Data.Foldable 模块中的 foldMap,该模块概括了整个“映射然后组合”功能。 Foldable typeclass 基本上只是意味着你可以在它上面使用folds,它也使用Monoid,这基本上只是意味着你有一种方法可以组合两个元素,例如列表的连接或数字的加法。或者,您也可以使用列表形成 Monad 的事实,并使用 >>= 运算符作为

> [1, 2, 3] >>= show
"123"

最后,所有这些操作几乎可以归结为对每个元素应用一个函数,然后使用其他函数将这些结果组合在一起。这是一个非常普遍的模式,可以在很多情况下应用,因此为什么会有它的概括。

【讨论】:

  • 非常感谢。这就是我一直在寻找的。​​span>
  • 在未来,foldMap show 可能是首选的表达方式。
  • @Ingo 我们必须先看看 FTP 是如何用于 GHC 7.10 版本的。就我个人而言,我赞成燃烧桥梁的提议,我认为将 Foldable 和 Traversable 集成到 Prelude 中会很棒,但我明白这会使 Haskell 的初始学习曲线更加困难。
  • 在列表 Monad 实例中提及 (>>=) = flip foldMap 可能是个好主意,因此可以写为 [1, 2, 3] >>= show
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-24
  • 2020-01-05
  • 2020-04-11
  • 1970-01-01
  • 2021-08-18
相关资源
最近更新 更多