[英]Define function in Haskell using foldr
我正在尝试使用foldr函数在Haskell中定义一个函数:
fromDigits :: [Int] -> Int
该函数获取一个Int列表(每个Int的范围从0到9)并转换为单个Int。 例如:
fromDigits [0,1] = 10
fromDigits [4,3,2,1] = 1234
fromDigits [2,3,9] = 932
fromDigits [2,3,9,0,1] = 10932
无论如何,我毫不费力地使用显式递归甚至使用zipWith定义了这一点:
fromDigits n = sum (zipWith (*) n (map ((^)10) [0..]))
但是现在我必须使用文件夹来定义它,但是我不知道如何获得10的幂。
fromDigits xs = foldr (\x acc -> (x*10^(???)) + acc) 0 xs
如何减少它们? 我知道我可以从(length xs-1)开始,但是那又如何呢?
最好的祝福
约的好处foldr
的是,它是如此extemely容易想象!
foldr f init [a,b, ... z]
≡ foldr f init $ a : b : ... z : []
≡ a`f b`f`... z`f`init
≡ f a (f b ( ... (f z init)...)))
如您所见,第j个列表元素用于f
j个连续调用中。 head元素只传递一次到函数的左侧。 对于您的应用程序,head元素是最后一位数字。 那应该如何影响结果? 好吧,它只是添加到结果中,不是吗?
15 = 10 + 5
623987236705839 = 623987236705830 + 9
- 明显。 然后的问题是,您如何照顾其他数字? 好吧,要使用上述技巧,您首先需要确保在携带的子结果的最后一位为0。 来自提供的数字的0! 您如何添加这样的零?
这实际上应该已经足够了。
您几乎在那里:
你的
fromDigits xs =文件夹(\\ x acc->(x * 10 ^(???))+ acc)0 xs
有2个小更改的解决方案:
fromDigits =文件夹(\\ x acc-> acc * 10 + x)0
(顺便说一句,我在两边都省略了xs
,这不是必需的。
另一种选择是
fromDigits = foldl(\\ x acc->读$(显示x)++(显示acc))0
诀窍是,您不需要每次都从头开始计算10的幂,只需要根据以前的10的幂(即乘以10)来计算它。 好吧,假设您可以反转输入列表。
(但是您在上面给出的列表已经是相反的顺序,因此可以说您应该能够将它们反向,并且只需说您的函数以正确的顺序获取数字列表即可。如果没有,则除以10而不是乘以10。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.