首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用折叠*在Haskell中生成列表

使用折叠*在Haskell中生成列表
EN

Stack Overflow用户
提问于 2017-06-12 16:39:03
回答 1查看 878关注 0票数 0

我试图在Haskell中解决以下问题:给定一个整数,返回它的数字列表。约束条件是,我只需要使用一个折叠*函数(* = {r,l,1,l1})。

没有这样的约束,代码很简单:

代码语言:javascript
复制
list_digits :: Int -> [Int]
list_digits 0 = []
list_digits n = list_digits r ++ [n-10*r] 
                where
                     r = div n 10

但是,如何使用折叠*从空列表中从本质上增长一个数字列表呢?

提前谢谢。

EN

回答 1

Stack Overflow用户

发布于 2017-06-14 15:05:16

虽然unfoldr可能是分配的意思,但如果您使用foldr作为同胚,即建立一个列表,而另一个列表却被撕毁,您可以使用foldr编写这个列表。

代码语言:javascript
复制
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变得偏颇:

代码语言:javascript
复制
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)

这在非正数上的行为略有不同:

代码语言:javascript
复制
>>> 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]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44504534

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档