我是 Haskell 的新手,我有以下代碼:
second (x:y:xs) = y : second xs -- returns every second element of a list
second _ = []
xs = [1,2,3,4] second xs
我希望xs被評估為[1,2,3,4,2,4,4],因為那是不動點,即[1,2,3,4,2,4,4] == [1,2,3,4] second [1,2,3,4,2,4,4]。
但是,當我嘗試xs在 GHCi 中進行評估時,我得到
Prelude> xs
[1,2,3,4,2,4,4
但它不會停止計算。
誰能解釋為什么這不會停止,是否有一種簡單的方法可以使計算停止并回傳[1,2,3,4,2,4,4]?
uj5u.com熱心網友回復:
[1,2,3,4,2,4,4] []是的不動點([1,2,3,4] ) . second,但不是最不固定的點。
也就是說[1,2,3,4,2,4,4] undefined,哪個更小。從某種意義上說,它比第一個定義更小。
第一個更明確,因為它定義了第 7 個尾巴,而第二個的第 7 個尾巴是undefined。
這是普遍的看法。但具體來說,我們可以一步一步地進行計算,命名所有中間值并擴展定義,我們會發現結果上的“get”點趕上了最初更遠的“put”點,但是“get”點比“put”快兩倍。因此,當他們見面時,我們已經在那里放置了我們可以獲得的任何東西。
因此,計算卡住了,等待什么東西出現在什么都沒有的地方,也沒有什么東西可以放在那里。
避免這種情況的唯一方法是把take 7它放在上面。
在一個不相關的注釋中,我會稱該函式為seconds,而不是second。
所以它是這樣的:
xs = [1,2,3,4] second xs
a b c (_:a:p) = xs = [1,2,3,4] second xs
↓ ↓ ↓ (_:b:q) = p = [ 3,4,2] second p
= 1 2 3 4 2 4 4 (_:c:r) = q = [ 2,4] second q
↓ ↓ ↓ ↓ r = [ 4] second r
a b c
↑ ↑ ↑ ↑ r = drop 2 q = second q =
xs p q r = second (2:4:r) = 4:second r
head r 定義明確,它是
r = drop 2 q = second q
= second (_:c:r)
= c:second r
head r = c = 4
tail r =
但接下來我們需要找到tail r. 是(:)資料節點嗎?是[]嗎?
= tail (c:second r)
= second r -- (1)
= second (c:second r)
= case (c:second r) of
(x:y:z) -> y:second z
[] -> []
= case (second r) of -- (2)
(y:z) -> y:second z
因此,要找出second r( (1)) 是什么,我們需要找出( ) 是什么second r(2)。
我們被困住了。
uj5u.com熱心網友回復:
另一種更直觀的方式是[](串列末尾)必須來自某個地方。該second函式只有在輸入中[]遇到 a時才會回傳[],因此您最終會遇到雞和蛋的情況。在這種情況下,[]永遠不會產生,因此計算永遠不會停止。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/316869.html
