【问题标题】:Custom 'fold' function needs counter自定义“折叠”功能需要计数器
【发布时间】:2023-03-12 12:16:01
【问题描述】:

我的作业非常顺利,直到我偶然发现了最后一项任务。
首先,我必须定义一个自定义的List 结构:

data List a = Nil | Cons a (List a) deriving Show

另一个任务是编写一个自定义的fold 函数:

foldList :: (a -> b -> b) -> b -> List a -> b
foldList f b Nil        = b
foldList f b (Cons a l) = f a (foldList f b l)

第二个参数是在列表末尾(Nil 元素处)使用的值。

我还必须编写一个函数prodList,将提供的列表中的每个元素相乘:

prodList :: List Int -> Int
prodList = foldList (\x y -> x * y) 1

末尾的1 是乘法的中性元素。因此它对计算没有影响。

不过,我很难解决最后一个问题。
我必须编写一个函数binList 来计算表示二进制数的列表的十进制值。最低有效位是列表的第一个元素,因此二进制数是相反的。
一个给定的例子是binList (Cons 1 (Cons 0 (Cons 0 (Cons 0 (Cons 1 Nil))))) 的结果应该是 19(因为 (10001)_2 是 (19)_10)。然而,列表 [1,1,0,1] 的结果应该是 (1011)_2=(11)_10)。
作业的罪魁祸首是,我们必须使用foldList

我知道如何计算每个数字,但我很难找到一种方法来找出我目前所在的索引i

binList :: List Int -> Int
binList = foldList (\x y -> 2^i*x + y)

在 Haskell 中可能有一个很好的、咖喱的方法来解决这个问题。你能告诉我你将如何解决这个任务吗?

【问题讨论】:

  • 你不需要知道你在什么索引。 (提示:如果你有 10 位,最重要的需要乘以 2、9 倍……那是它在列表右侧的位数……嗯……)
  • 该函数基于每个元素应用。指数i 随列表的每个元素而变化。我不知道如何在不知道确定指数的索引的情况下做到这一点。
  • o.O 就是这么简单!感谢您的提示!完全忘记了这样做的方式! :D

标签: haskell counter fold


【解决方案1】:

如果你要写出计算,它看起来像这样:

x0 + 2 * x1 + 4 * x2 + 8 * x3 + ...

这可能表明您需要使用索引,但如果您分解此表达式,则会得到以下结果:

x0 + 2 * (x1 + 2 * (x2 + 2 * (x3 ...

你现在明白它是怎么写成折叠的了吗?请注意,有一个看起来像这样的自相似性:

x + 2 * x'

希望这对你来说已经足够了:)

【讨论】:

  • 好的,非常感谢! @alternative 已经给出了这个提示,我刚刚编写了代码。这行得通!有时我就是只见树木不见森林。 :D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多