【问题标题】:Haskell Just iterate through listHaskell 只是遍历列表
【发布时间】:2018-09-09 10:21:53
【问题描述】:

我尝试简单地遍历一个列表并返回每个元素。

iterateList [] =  error "empty list"
iterateList [a] = a
iterateList (x:xs) = x iterateList xs

在第三行,我尝试返回第一个元素,然后递归调用 List 尾部的 iterateList

但这不起作用。知道为什么吗?

示例: 输入:迭代列表 [1,2,3,4,5] 输出:1 2 3 4 5

【问题讨论】:

  • 您的问题不清楚 - 如果您“返回列表的每个元素”,您将获得原始列表。你想以某种方式处理元素吗?
  • @simplesystems 您认为示例中的“空间”是什么?你想打印列表的每个元素,它们之间有一个空格吗?在 Haskell 中,打印是一项比您想象的更复杂的任务,并且与仅仅“返回”有很大不同。
  • 首先,您需要停止循环思考。接下来,您可以使用列表本身来完成所有这些事情。
  • 一个好的起点可能是Learn you a Haskell chapter on lists。它有简单列表操作的例子,后面的章节有很多更有趣的对列表进行操作的函数。
  • @simplesystems:但是在函数式编程中,您不会考虑循环,而是考虑函数。此外,所有数据都是不可变的:您无法更改列表、其元素或这些元素的字段。

标签: list haskell iteration


【解决方案1】:

我想要的只是 Java 中的 for 循环示例,我可以对列表中的每个元素执行一些操作,例如打印、求和、乘法、删除,只需访问这些元素

嗯,你不能在 Haskell 中“删除”任何东西,你也不能修改绑定。你可以做的是例如对元素求和:

sumList [] = 0
sumList (x : xs) = x + sumList xs

或将元素相乘:

productList [] = 1
productList (x : xs) = x * productList xs

此时您可能会意识到自己重复了很多次,这很烦人。您可以提取公共部分并将差异转换为参数:

iterateList f z [] = z
iterateList f z (x : xs) = x `f` iterateList f z xs

sumList     = iterateList (+) 0
productList = iterateList (*) 1

这里z 表示要为空输入列表返回的“基值”,f 是“组合”函数,告诉它如何处理元素和列表的其余部分。

打印有点复杂,因为您必须先了解IO 的工作原理(特别是,您应该了解>>return),但仍然可以做到:

doNothing           = return ()
printAndThen x rest = print x >> rest

printList = iterateList printAndThen doNothing 

... 或直接使用值而不是先将它们绑定到名称:

printList = iterateList (\x rest -> print x >> rest) (return ())

最后你会意识到你刚刚重新发明了foldr。 :-)

【讨论】:

    猜你喜欢
    • 2011-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-17
    • 1970-01-01
    • 2022-10-12
    • 1970-01-01
    相关资源
    最近更新 更多