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