1

任务是定义一个函数decimal :: [Int] -> Int,其中一个正整数列表给出十进制数西格玛函数,以便该列表[1,4,3,1,9]返回Integer14319。我将使用该fold函数。

我真的没有从这里开始的好主意,所以我只需要朝着正确的方向前进,但我正在考虑霍纳计划。谢谢!

4

4 回答 4

5

在折叠中,您从左侧开始并向右移动。当您使用列表中的下一个元素时,您将已有的元素乘以 10 并将新元素添加到其中。

因此,如果您将 foldl 设为 0 并具有 [1,2,3],则您的函数会将当前 (0) 乘以 10(也是 0),然后加 1。继续,将当前 (1) 乘以 10(到得到 10) 并加上 2 (12)。最后是 3, 12 * 10 = 120, 120 + 3 = 123。

这应该很容易编码:)

于 2013-09-27T11:17:04.637 回答
3

也许这个等式会指导你。

S_n = \sum_{k=0}^n x_k 10^{nk} = \sum_{k=0}^{n-1} x_k 10^{nk} + x_n = 10\sum_{k=0}^{ n-1} x_k 10^{(n-1)-k} + x_n = 10S_{n-1} + x_n

于 2013-09-27T11:14:11.317 回答
1

由于这是一个家庭作业,让我们停止建议您将这个表达式扩展为一些列表,并尝试提取一个循环关系:

x_0*10^n+x_1*10^(n-1)+...+x_n*10^0 = (((x_0*10+x_1)*10+x_2)...)*10+x_n

如果将其与折叠进行比较,您将看到一个折叠与两个参数的特定函数的此模式匹配。

于 2013-09-27T11:15:55.927 回答
-3

这是我的变种

import Data.List
decimal :: [Int] -> Int
decimal xs = foldl' (\sum (pos,x) -> (sum + x*(10^(l-pos)))) 0 $ zip [1..] xs where
            l = length xs


*Main> decimal [1,4,3,1,9]
14319

Haskell中,您拥有非常强大的武器 - 列表处理功能。其中一个函数是foldl(我们使用严格版本的foldl, foldl')它的类型

foldl :: (a -> b -> a) -> a -> [b] -> a

这个函数接受 thre 参数、一个累加 agrument、一个已处理的列表,以及最感兴趣的函数,它使用累加器和列表元素执行任何操作并返回结果。折叠是非常重要的功能,因此您应该阅读有关它的详细手册
但是,有一个问题,我们的方程中有三个变量:处理的列表元素(x),列表总长度(n)和处理元素的位置(k)。但是我们只能遍历到foldl一个元素。我们如何遍历每个元素的位置?让我们形成元组,Int其中第一个元素是一个位置,第二个是一个值。这是一个标准技巧,zip函数可以帮助我们:

zip [1..] [1,4,3,4,6]
[(1,1),(2,4),(3,3),(4,4),(5,6)]

然后我们将元组列表传递给foldl函数,并foldl调用lambda function (\sum (pos,x) -> (sum + x*(10^(l-pos))))列表的每个元素,将结果求和sum

于 2013-09-27T11:28:54.097 回答