簡體   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