mult_add是一个真正的函数吗?它有什么作用?

时间:2012-06-11 22:51:47

标签: haskell

我有以下问题给我。

  

编写一个函数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]

1 个答案:

答案 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,条件是aNum的实例class(这样你就可以添加和乘以它们。)

您被要求使用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

好!我们现在有一个函数需要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 xsf的每个元素之间插入函数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