我试图在Haskell中解决以下问题:给定一个整数,返回它的数字列表。约束条件是,我只需要使用一个折叠*函数(* = {r,l,1,l1})。
没有这样的约束,代码很简单:
list_digits :: Int -> [Int]
list_digits 0 = []
list_digits n = list_digits r ++ [n-10*r]
where
r = div n 10但是,如何使用折叠*从空列表中从本质上增长一个数字列表呢?
提前谢谢。
发布于 2017-06-14 15:05:16
虽然unfoldr可能是分配的意思,但如果您使用foldr作为同胚,即建立一个列表,而另一个列表却被撕毁,您可以使用foldr编写这个列表。
digits :: Int -> [Int]
digits n = snd $ foldr go (n, []) places where
places = replicate num_digits ()
num_digits | n > 0 = 1 + floor (logBase 10 $ fromIntegral n)
| otherwise = 0
go () (n, ds) = let (q,r) = n `quotRem` 10 in (q, r : ds)实际上,我们在这里所做的是使用foldr作为“状态映射”。我们提前知道我们需要输出多少位数(使用log10),而不是这些数字是什么,所以我们使用单位(())值作为这些数字的后备值。
如果你的老师只是在顶层拥有一台foldr,那么你可以让go变得偏颇:
digits' :: Int -> [Int]
digits' n = foldr go [n] places where
places = replicate num_digits ()
num_digits | n > 0 = floor (logBase 10 $ fromIntegral n)
| otherwise = 0
go () (n:ds) = let (q,r) = n `quotRem` 10 in (q:r:ds)这在非正数上的行为略有不同:
>>> digits 1234567890
[1,2,3,4,5,6,7,8,9,0]
>>> digits' 1234567890
[1,2,3,4,5,6,7,8,9,0]
>>> digits 0
[]
>>> digits' 0
[0]
>>> digits (negate 1234567890)
[]
>>> digits' (negate 1234567890)
[-1234567890]https://stackoverflow.com/questions/44504534
复制相似问题