繁体   English   中英

使用文件夹在Haskell中定义函数

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM