我有以下问题给我。
编写一个函数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
上找不到任何内容。我认为mabye是函数名称,但她希望form_number_back
作为函数名。这意味着mult_add
是一个Haskell函数。
任何人都可以向我解释mult_add
的作用吗?它甚至写得对吗?是mult_add
另一个用户自制的函数我应该用我自己的代码吗?
编辑2
我尝试输入函数示例来获取其类型.. 所以.. form_number_back [1,2,3,4] :: Num b => b - > [b] - > B'/ P>
所以我的功能看起来像
form_number_back a = foldr(mult_add)
但是正在返回
的类型form_number_back :: Num b => [t] -> b -> [b] -> b
试图弄清楚如何摆脱[t]
答案 0 :(得分: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需要a
和另一个a
,并返回a
,条件是a
是Num
的实例class(这样你就可以添加和乘以它们。)
您被要求使用foldr
来编写此函数,所以让我们看看它的类型:
Prelude> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
这看起来有点令人生畏,所以让我们分解吧。第一部分(a -> b -> b)
告诉我们foldr
需要两个变量a
和b
的函数。好吧,我们已经有一个 - 它是mult_add
。那么,如果我们将mult_add
作为foldr
的第一个参数提供,那么会发生什么?
Prelude> :t foldr mult_add
foldr mult_add :: Num b => b -> [b] -> b
好!我们现在有一个函数需要b
和[b]
(b
s列表)并返回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
在f
的每个元素之间插入函数xs
,并且另外将x
放在列表的末尾,并且从右边收集所有内容(这就是为什么它被称为正确折叠)。所以,例如:
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