【问题标题】:Iterating through a list of tuples with Haskell使用 Haskell 遍历元组列表
【发布时间】:2018-10-03 15:10:18
【问题描述】:

我有一个元组列表

   list =  [(1,2,4),(4,1,4),(3,7,2),(4,2,5),(1,5,9)]

我想遍历列表并单独获取每个元组。 例如,也许打印

(1,2,3)

(4,1,4)

(3,7,2)

等等。

我在访问列表中的项目时遇到问题,因为如果我要执行 list!!1,如果我尝试 list!!3,我将无法访问所有其他元素。

一种方法如何使用 haskell 遍历元组列表?

【问题讨论】:

  • 这些是列表中的元组。
  • 这是一个三元组的列表,而不是列表的列表。
  • 你使用什么资源来学习 Haskell?我建议阅读有关列表和递归的模式匹配。然后你可以尝试使用例如map 或 mapM,那么你可以尝试自己实现这两个函数
  • mapM_ print [(1,2,4),(4,1,4),(3,7,2),(4,2,5),(1,5,9)]怎么样
  • (!!) 在 Haskell 中并不经常需要。如果您需要挑选列表中的特定元素,则表明您应该使用产品类型而不是列表。

标签: haskell functional-programming


【解决方案1】:

您的问题并非特定于元组列表,您需要知道如何遍历任何内容的列表。

传统上,由于您没有循环,因此函数式语言中的“迭代”是通过递归完成的,因此合理的第一个解决方案如下所示:

printAList [] = return ()
printAList (x:xs) = do
  print x
  printAList xs

当然,每次你想遍历一个列表时都写一个递归是很愚蠢的,所以所有函数式语言都包含高阶函数,它在参数中接受一个函数来指示如何处理每个元素列表以及如何组合结果。经常看到的这样一个函数是map,它使用每个元素上传递的函数的结果创建一个新列表:

map f [] = []
map f (x:xs) = f x : map f xs

所以在这里你可能会想到做map print yourList。不幸的是,print 并没有真正显示它的参数,它是一个创建 IO 操作的函数,在执行时会显示参数。因此,您将使用地图获取操作列表并执行它,您必须使用执行操作列表的函数:sequence_(_ 表示我们不关心每个操作的返回)

sequence_ [] = return ()
sequence_ (act : acts) = do
  act
  sequence_ acts

所以你的最终代码是sequence_ (map print yourList)。当然,将动作创建函数应用于列表元素并执行它们是非常频繁的需要,您需要为此提供专用函数:mapM_(M 表示这是 map 的“单子”版本,而_ 我们在执行后丢弃结果)。

mapM_ f xs = sequence_ (map f xs)

TL:DR 所以要显示你的每个元组,你只需要写mapM_ print yourList

【讨论】:

  • mapM_ 也可以替换为traverse_ print xs——或其翻转表亲for_ xs print——可以在更多地方使用,因为它们只需要Applicative 约束而不是Monad .没有_ 的这些函数的版本也是如此,它们会累积结果。 mapMApplicative 成为 Monad 的超类之前的历史产物。
  • 您当然是对的,但我应该将 sequence_ 替换为 sequenceA_ 吗?我可能仍然会给出这些函数的列表版本(只是添加一个注释来说明这些函数可以与其他一些“容器”一起使用)
猜你喜欢
  • 2019-03-17
  • 2011-11-25
  • 1970-01-01
  • 1970-01-01
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 2018-09-09
  • 1970-01-01
相关资源
最近更新 更多