tl;博士
20 < length $ take 10 $ whatever需要whatever成功地對串列進行模式補丁(至少是[]或)的事實不是(_:_)“缺乏”懶惰嗎?
或者,換句話說,為什么不是(20 >) . length . take 10 === const True,因此將它們中的任何一個應用于任何事物都不需要對論點進行任何評估?
是(20 >) . length . take 10 !== const True必需品嗎?還是設計選擇?無論哪種情況,為什么?
前言
這是對我之前的問題的跟進。
在那里我問為什么重復和無限fix error列印。*** Exception:
答案令人滿意。
我的潤滑
但是,我玩了一下ghci并意識到take 0 $ fix error預期回傳""和length $ take 0 $ fix error回傳0。
另一方面,以下列印*** Exception: 無限流:
20 > (length $ take 10 $ fix error)
我知道,即使計算了一個元素fix error(實際上是嘗試),結果就是它,但我的問題是:為什么首先需要在那個特定的運算式中對它們中的任何一個進行評估?畢竟,length $ take 10 $ whatever不能是<= 10,因此< 20,所以運算式的計算結果應該是True。
實際上,我看到它20 > (length $ take 10 $ [fix error])立即回傳True. 可能整點是take 10期望在 a 上作業[a],因此length $ take 10 $ [fix error]不需要評估fix error以確保它在 a 上作業[a]。事實上,我也驗證了這些20 > (length $ take 10 $ undefined)錯誤(即使沒有無限重復的錯誤),而20 > (length $ take 10 $ [undefined])回傳True.
也許這就是Willem Van Onsem 在此評論中的意思。
無論如何,因為我可以把上面的運算式寫成
((20 >) . length . take 10) $ fix error
我很想說
(20 >) . length . take 10 === const True
因此我會說像((20 >) . length . take 10) $ fix errorreturnTrue一樣const True $ fix errorreturn是合理的True。
但事實并非如此。為什么?
uj5u.com熱心網友回復:
take 10必須確定它的引數是否是一個[]或(:)值。
const True才不是。
length是嚴格的,因為它必須迭代其整個論點。組合并不意味著它只需要迭代足夠多的值來獲得足夠大的數字來偽造(20 >)。
uj5u.com熱心網友回復:
畢竟,長度 $ 取 10 $ 不能是 <= 10 [...]
在 Haskell 中不正確。長度函式通常可能會崩潰或進入無限回圈。在這兩種情況下,它都不會給出有效的整數作為結果,并且無法將缺少的有效整數與 10 進行比較。通常,評估任意運算式可能會產生一個值,例如 (1::Int) 或bottom。底部概括了運算式可能不會產生值的所有原因。
因此,運算式20 < length $ take 10 $ whatever必須計算為任一True或底部,對于編譯器False來說甚至是一個選項。如您所見,兩者True都是bottom有效的結果。相比之下,const True whatever是不同的,因為它總是在True不評估的情況下評估whatever。
uj5u.com熱心網友回復:
您看到的行為與length和>比與take. length必須回傳一個特定的數字,并且(20 >)只能在提供特定數字時運行。您認為管道中間正在處理什么數字?
您承認這length $ take 10 $ fix error是(并且應該是)底部。在遇到錯誤之前,甚至沒有一個fix error可以查看的串列元素,因此沒有可以回傳的數字可以準確測量串列的長度。(可能很容易說它的長度可能為零,因為那里沒有任何元素,但這意味著它fix error等于[],這也不正確。真正要求它的長度只是一個錯誤。)
但是,您現在想要將該底部值輸入(20 >)并期望得到結果True。但是底部是可以互換的,所以這也需要20 > undefinedis True。事實上,它也length $ take 50 $ fix error需要是.True
您的直覺似乎length . take 10是無法回傳大于 10 的值,因此(20 >) . length . take 10應該是const True,因此不需要檢查其輸入。您顯然已經注意到這對于當前的 Haskell 來說是不準確的,但我認為這無論如何都不是可取的行為。我的直覺是,(20 >)需要一個小于 20的特定True輸入數字才能回傳;一個模糊的概念認為它的輸入不能是一個更大的數字是不夠的。如果其輸入是錯誤(任何錯誤),則既不是True也不False是準確的回傳值。
請注意,這length $ take 0 $ fix error是一個非常不同的情況。take等效于以下定義:
take n _
| n <= 0 = []
take _ [] = []
take n (x:xs) = x : take (n - 1) xs
它在檢查任何串列之前檢查要獲取的元素的數量是否為零(或更少),如果是,它可以在不檢查輸入串列的情況下回傳特定的具體[]串列(因此不會從fix erroror觸發任何錯誤undefined。然后length可以測量[]和回傳0,小于20。
類似地,length $ take 10 $ [fix error]因為take 10可以回傳長度為 1 的串列而無需檢查串列中的任何元素(并且該位觸發錯誤),并且length可以測量該串列并回傳1小于20.
這兩種情況實際上都不需要任何未定義的屬性的特定值,但是您的原始情況確實需要(length錯誤的)。這與“確保我們正在努力”無關[a],只是您的答案是否取決于未定義的值。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/474030.html
