[英]Haskell, list of natural number
我是 Haskell 的絕對新手,但試圖了解它是如何工作的。
我想編寫自己的惰性整數列表,例如 [1,2,3,4,5...]。
對於我寫的列表
ones = 1 : ones
嘗試后,效果很好:
*Main> take 10 ones
[1,1,1,1,1,1,1,1,1,1]
我怎樣才能對遞增的整數做同樣的事情?
我試過這個,但它確實失敗了:
int = 1 : head[ int + 1]
在那之后,我如何制作一個將兩個流相乘的方法? 如:
mulstream s1 s2 = head[s1] * head[s2] : mulstream [tail s1] [tail s2]
int = 1 : head [ int + 1]
不起作用的原因是:
:
需要是一個列表。 int + 1
嘗試添加列表和數字,這是不可能的。 創建從1到無窮大的列表的最簡單方法是[1..]
要以1以外的步數計數,可以使用[firstElement, secondElement ..]
,例如,創建所有正奇數整數的列表:[1,3 ..]
要獲得形式[x, fx, f (fx), f (f (fx)),...]
無限列表,您可以使用iterate fx
,例如iterate (*2) 1
將返回列表[1, 2, 4, 16,...]
。
要在兩個列表的每對元素上成對應用操作,請使用zipWith:
mulstream s1 s2 = zipWith (*) s1 s2
為了使這個定義更簡潔,您可以使用無點形式:
mulstream = zipWith (*)
對於自然數,您必須使用map:
num1 = 1 : map (+1) num1
或者理解:
num2 = 1 : [x+1 | x <- num2]
或者當然:
num3 = [1..]
我不確定這是不是你問的問題,但在我看來,你想要建立一個增加自然數的列表,而不依賴於任何其他列表。 所以,通過這個標記,你可以做一些事情
incr a = a : inrc (a+1)
lst = inrc 1
take 3 lst
=> [1,2,3]
從技術上講,這被稱為累積函數(我相信),然后我們所做的就是使用'lst'輕松使用它的特殊情況
你可以從那里發瘋,做的事情如下:
lst = 1 : incr lst where incr a = (head a) + 1 : incr (tail a)
take 3 lst
=> [1,2,3]
等等,雖然這可能依賴於你還沒有學到的東西(在哪里) - 通過OP判斷 - 但它仍然應該很容易閱讀。
哦,對,然后是列表乘法。 好吧,你可以使用上面提到的zipWith(*),或者你可以像這樣重新發明輪子(它更有趣,相信我:)
lmul a b = (head a * head b) : lmul (tail a) (tail b)
safemul a b = take (minimum [len a, len b]) (lmul a b)
我相信,你可以通過試驗這個功能找到安全的原因,但它與'尾'有關。 問題是,沒有空列表,列表不匹配等情況,所以你要么必須將各種定義(lmul _ [] = [])或者使用警衛和/或等等一起破解。 ...或堅持使用zipWith :)
語言中有這樣的語法:
take 10 [1,2..]
=> [1,2,3,4,5,6,7,8,9,10]
你甚至可以做出不同的進步:
take 10 [1,3..]
=> [1,3,5,7,9,11,13,15,17,19]
您可以定義一個最多達到某個數字的列表,然后通過保持前者不變來將第一個與第二個相加,如下所示:
naturals :: Integer -> [Integer]
naturals n
| n <= 0 = []
| otherwise = nat n []
where
nat 1 a = (1:a)
nat n a = nat (n-k) (nat k a)
where
k = (n-1)
sumNaturals :: [Integer] -> [Integer]
sumNaturals l = sumRight l []
where
sumRight [] a = a
sumRight (x:[]) a = (x:a)
sumRight (x:y:zs) a = sumRight (x:a) (sumRight (sum (x:y:a):zs) a)
由於它們都是 1,您可以通過更改它們總和的順序,以您喜歡的任何方式增加它們,從左到右,到中間點等等。 您可以使用以下方法測試最多一百(或更多):
(sumNaturals . naturals) 100
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.