0

我有以下问题。

编写一个函数 form_number_back,它接受一个正整数列表,并使用列表中的数字以相反的顺序形成一个十进制数。

例如 form_number_back [1, 2, 3, 4] 应该返回数字 4321;form_number_back [ ] 返回 0

使用下面的函数 foldr 和 mult_add 来完成这个mult_add d s = d + 10*s

注意:foldr 和 foldr1 是两个不同的函数。尝试在您的定义中使用 foldr1 而不是 foldr 并查看是否使用空列表获得相同的结果。解释你的结果。

我在 上找不到任何东西mult_add。我以为可能是函数名,但她想要form_number_back作为函数名。这意味着mult_add是一个 Haskell 函数。

谁能向我解释是什么mult_add?它甚至写对了吗?mult_add我应该与我自己的代码一起使用另一个用户制作的功能吗?

编辑 2

我尝试放入函数示例以获取其类型.. 所以.. form_number_back [1, 2, 3, 4] :: Num b => b -> [b] -> b

所以我的功能看起来像

form_number_back a = foldr(mult_add)

但返回类型

form_number_back :: Num b => [t] -> b -> [b] -> b

试图弄清楚如何摆脱它[t]

4

1 回答 1

4

与大多数其他语言相比,Haskell 中的类型更重要且信息量更大。当您不了解 Haskell 时,最好的第一步是考虑类型。所以让我们这样做。我们将启动 ghci 并输入:

Prelude> let mult_add d s = d + 10 * s

现在询问它的类型:

Prelude> :t mult_add
mult_add :: Num a => a -> a -> a

也就是说, mult_add 接受 ana和 another a,并返回 an a,附带条件a是类的实例Num(以便您可以将它们相加和相乘)。

你被要求使用foldr来编写这个函数,所以让我们看看它的类型:

Prelude> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b

这看起来有点吓人,所以让我们分解一下。第一部分,(a -> b -> b)告诉我们foldr需要两个变量的函数,ab。好吧,我们已经有了其中之一 - 它是mult_add. 那么如果我们mult_add作为第一个参数输入会发生foldr什么呢?

Prelude> :t foldr mult_add
foldr mult_add :: Num b => b -> [b] -> b

好的!我们现在有一个函数,它接受 ab和 a [b]bs 的列表)并返回 a b。您尝试编写的函数需要在0给定空列表时返回,因此让我们尝试将空列表提供给它,并为其余参数提供一些不同的值:

Prelude> foldr mult_add 10 []
10
Prelude> foldr mult_add 5 []
5

嘿,这很有趣。如果我们给它输入数字x和空列表,它只会返回x注意:这总是正确的foldr。如果我们给它初始值x和空列表[],它会返回x,无论我们使用什么函数代替mult_add。)

因此,让我们尝试将其0作为第二个参数提供:

Prelude> foldr mult_add 0 []
0

这似乎行得通。现在如果我们给它提供列表[1,2,3,4]而不是空列表呢?

Prelude> foldr mult_add 0 [1,2,3,4]
4321

好的!所以它似乎工作。现在的问题是,为什么它会起作用?理解的诀窍foldr是在 的每个元素之间foldr f x xs插入函数,另外放在 列表的末尾,并从右侧收集所有内容(这就是为什么它被称为折叠)。因此,例如:fxsx

foldr f 0 [1,2,3] = 1 `f` (2 `f` (3 `f` 0))

其中反引号表示我们正在使用中缀形式的函数(所以它的第一个参数是左边的那个,第二个参数是右边的那个)。在您的示例中f = mult_add,您有 将其第二个参数乘以 10 并将其添加到第一个参数:

d `mult_add` s = d + 10 * s

所以你有了

foldr mult_add 0 [1,2,3] = 1 `mult_add` (2 `mult_add` (3 `mult_add 0))
                         = 1 `mult_add` (2 `mult_add` 3)
                         = 1 `mult_add` 32
                         = 321

这符合您的期望。为了确保您理解这一点,请弄清楚如果您mult_add以相反的方式定义会发生什么,即

mult_add d s = 10 * d + s
于 2012-06-12T09:43:45.297 回答