[英]Potentially infinite list of tuples in Haskell
我有一个我无法解决的问题。 这是除数的后续任务。
第一个是定义一个函数,该函数将数字k的所有正除数放入列表中
编辑:意外地写了错误的代码(这是当您有一个函数除数和除数时得到的...只是在玩弄清楚列表的反应方式。)关于列表中有多个的问题,这不应该发生在这里,但是速度要慢得多。
divisor :: Int -> [Int]
divisor k = divisor' 1 k
where
divisor' n k | n > k = []
| k `mod` n == 0 = (n:result)
| otherwise = result
where result = divisor' (n+1) k
到现在为止还挺好。
我接下来的任务是编写一个函数,该函数返回一个元组(x,xs)
列表,其中x
是自然数/= 0
而xs
是x
的所有正数的列表。
它看起来应该像这样:
take 7 trueDivisors
[(1,[]),(2,[1]),(3,[1]),(4,[1,2]),(5,[1]),(6,[1,2,3]),(7,[1])]
( take
代表究竟是什么?现在可能是我的问题,我重新阅读任务。通常函数只得到他们的名字叫......就先trueDivisors k
工作)
我已经尝试了很多,例如使用第一个函数将除数显示在元组的列表中,但没有成功。 语法错误超过语法错误。
也许有人可以帮我一点忙,或者给我提示。 不幸的是,脚本中没有类似的东西。 谷歌也不是很热衷。
提前致谢 !
这是一个提示。 如果map divisors [1..7]
,则会得到:
[[1,1],[1,2],[1,3],[1,2,2,4],[1,5],[1,2,3,6],[1,7]]
这些是要创建的关联列表的第二个组件,除非您有一个小错误,除非允许多次返回相同的除数。 (提示:您可以使用filter
编写一个很好的单divisors
版本,但是一个快速的解决方法是Data.List.nub
。)您想返回:
[(1,[1]),(2,[1,2]),(3,[1,3]),(4,[1,2,4]),...]`
解决此问题的一种简单方法是编写一个辅助函数makeAssoc :: Int -> (Int, [Int])
,然后map makeAssoc [1..]
。 该函数可以调用divisors
。
另一个是采用两个列表[1..]
和(map divisors [1..])
。 第一个具有[Int]
类型,第二个具有[[Int]]
类型,并且您希望结果具有[( Int, [Int] )]
。 因此,请在Prelude
中寻找一个函数,该函数会将两个[a]
和[b]
类型的列表压缩为对[(a,b)]
对的列表。 也就是说,查找具有类型签名[a] -> [b] -> [(a,b)]
函数,然后查看它们是否满足您的要求。
如果弄清楚类型似乎很复杂,请不要担心:您可以让GHC帮您做到! 如果你写
divisorAssocs :: [( Int, [Int] )]
divisorAssocs = map _ is
where is :: [Int]
is = [1..]
GHC会将_
识别为打孔,并告诉您需要填充的内容:
• Found hole: _ :: Int -> (Int, [Int])
同样,如果您用另一种方式写一个有洞的东西:
divisorAssocs :: [( Int, [Int] )]
divisorAssocs = _ is (map divisors is)
where is :: [Int]
is = [1..]
给你:
• Found hole: _ :: [Int] -> [[Int]] -> [(Int, [Int])]
在Haskell中,有限列表和无限列表之间并没有真正的区别。 问题是要您创建一个名为trueDivisors
的变量(尽管Haskell变量不会改变),其类型为[(Int, [Int])]
。
首先让我们看一下如何制作一些无限列表
myFirstInfiniteList :: [Int]
myFirstInfiniteList = [1..]
powers :: [Int]
powers = powers’ 1 where
powers’ n = n : n * 2
myThirdInfiniteList :: [(Int,[Int])]
myThirdInfiniteList = map it [1..] where
it n = (n, [1..n])
现在,Haskell事先不知道列表是否是无限的,因此,如果您尝试打印一个列表,它将永远持续下去。 因此,您可以使用take
函数,该函数返回列表的前n个元素(其中n是第一个参数)
我认为这应该足以让您现在自己解决它。
trueDivisors :: [(Int,[Int])]
trueDivisors = {- you need to do this -}
您如何将数字和除数配对?
一种简单的实现是:
pair n = (n, divisors n)
剩下的就是将对映射到自然数的无限序列,并采用所需数量的元素
take 7 $ map pair [1..]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.