【问题标题】:Need help storing the previous element of a list (Haskell)需要帮助存储列表的前一个元素 (Haskell)
【发布时间】:2019-11-09 12:27:33
【问题描述】:

我目前正在处理一项任务。我有一个名为gamaTipo 的函数,它将元组的值转换为我的教授先前定义的数据类型。 问题是:为了gamaTipo 工作,它需要接收一些前面的元素。 gamaTipo 的定义如下:gamaTipo :: Peca -> (Int,Int) -> Peca 其中Peca 是我的教授定义的数据类型。

我需要做的是创建一个接受元组列表并将其转换为Peca 数据类型的函数。我苦苦挣扎的部分是获取列表的前一个元素。即:假设我们有一个列表[(1,2),(3,4)],其中列表(1,2) 的第一个元素始终对应于Dirt Ramp(由教授定义的数据类型)。我必须创建一个函数convert :: [(Int,Int)] -> [Peca],为了计算元素(3,4),我需要先将(1,2)翻译成Peca,并将其用作前一个元素来翻译(3,4)

这是我迄今为止尝试过的:

    updateTuple :: [(Int,Int)] -> [Peca]
    updateTuple [] = []
    updateTuple ((x,y):xs) = let previous = Dirt Ramp
                                in (gamaTipo previous (x,y)): updateTuple xs

虽然我没有收到此代码的错误消息,但预期的输出不正确。如果我的问题不容易理解,我也很抱歉,英语不是我的母语,我很难表达自己。先感谢您! :)

【问题讨论】:

  • PecaDirtRamp 到底是什么?你能给我们他们的定义吗?
  • 其实,没关系。我想我可以在不知道他们的定义的情况下回答这个问题。
  • 如果您最终确实需要这些定义,我也可以在这里发布它们,但都是葡萄牙语,不知道它是否会有所不同。我可以尝试翻译它,但我不确定它是否正确
  • 不,我不需要它们——我实际上只是发布了一个答案。
  • 顺便说一句,这个问题做得很好。您已经坦率地说这是一项作业,解释了您的问题,展示了您的尝试,并提出了一个明确的问题,并给出了一个对其他学习者有用的答案。我们经常在这里收到“问题”,这些“问题”只是家庭作业的剪切和粘贴副本,所以这是一个令人耳目一新的变化。

标签: haskell


【解决方案1】:

如果我理解正确,你的程序需要有一个类似这样的基本结构:

updateTuple :: [(Int, Int)] -> [Peca]
updateTuple = go initialValue
  where
    go prev (xy:xys) =
        let next = getNextValue prev xy
        in prev : (go next xys)
    go prev [] = prev

基本上,这里发生的事情是:

  • updateTuple 是根据辅助函数 go 定义的。 (请注意,“辅助函数”不是标准术语,只是我决定这样称呼它)。
  • go 有一个额外的参数,用于存储之前的值。
  • go 的实现可以利用之前的值。
  • go 递归时,递归调用可以将新计算的值作为新的“先前值”传递。

这是 Haskell 中相当常见的模式:如果递归函数需要一个额外的参数,那么可以定义一个具有该额外参数的新函数(通常命名为 go)。那么原函数可以用go来定义。

【讨论】:

  • 所以在这种情况下,go 辅助函数所做的只是存储我将在 gamaTipo 中使用的前一个元素?
  • @Ramux05 完全正确。当你这样表达时,它实际上非常简单,但我发现这种模式在我自己的代码中非常有用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-02
  • 2022-01-15
  • 1970-01-01
  • 2018-05-21
  • 2020-07-10
相关资源
最近更新 更多