繁体   English   中英

Haskell中潜在的元组列表

[英]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是自然数/= 0xsx的所有正数的列表。

它看起来应该像这样:

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.

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