任务是定义一个函数decimal :: [Int] -> Int
,其中一个正整数列表给出十进制数,以便该列表[1,4,3,1,9]
返回Integer
14319。我将使用该fold
函数。
我真的没有从这里开始的好主意,所以我只需要朝着正确的方向前进,但我正在考虑霍纳计划。谢谢!
在折叠中,您从左侧开始并向右移动。当您使用列表中的下一个元素时,您将已有的元素乘以 10 并将新元素添加到其中。
因此,如果您将 foldl 设为 0 并具有 [1,2,3],则您的函数会将当前 (0) 乘以 10(也是 0),然后加 1。继续,将当前 (1) 乘以 10(到得到 10) 并加上 2 (12)。最后是 3, 12 * 10 = 120, 120 + 3 = 123。
这应该很容易编码:)
也许这个等式会指导你。
由于这是一个家庭作业,让我们停止建议您将这个表达式扩展为一些列表,并尝试提取一个循环关系:
x_0*10^n+x_1*10^(n-1)+...+x_n*10^0 = (((x_0*10+x_1)*10+x_2)...)*10+x_n
如果将其与折叠进行比较,您将看到一个折叠与两个参数的特定函数的此模式匹配。
这是我的变种
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