[英]Why haskell seq function makes first argument to WHNF?
我認為seq很難理解,因為它是WHNF的第一個論點。
如果seq將第一個參數設為范式,則很容易理解。
使用WHNF相比NF有什么好處?
為什么Haskell委員會選擇在seq函數中使用WHNF?
首先,Haskell的API在WHNF和NF之間沒有優先選擇:它同時提供seq
和deepseq
。
因此,也許您的問題是為什么WHNF根本存在? 簡而言之,這是最少的評估。 完整的計算將如下所示:
但是,Haskell很懶,它會嘗試進行盡可能少的計算以獲得最終結果。 例如,要計算列表l
的長度,Haskell必須知道l
是[]
還是_ : t
。 然后遞歸有關t
的相同問題。 因此,它只需要數量的構造函數:
在最終構造函數[]
。 根據定義,這是連續的WHNF,它們僅提取值的最外部構造函數。
最外層的構造函數是您必須真正了解對某個值進行操作所必須知道的最少信息,例如在的case of
選擇一個分支,例如length
恰好在上面。 這是WHNF勝過NF的興趣。
請注意,對於簡單的類型,如Int
,每個價值是自身的構造函數( 2
, -7
, 15
,......),所以WHNF = NF他們。
最后,您幾乎不需要關心所有這一切:盡可能快地執行程序是編譯器的工作。 在對foldl (+) 0 [1..100]
的求值中,如果您試圖弄清楚列表[1..100]
在NF中完成的時間,那將是完全錯誤的。 編譯器將此折疊轉換為該尾遞歸循環
let sum ret i =
if i == 100 then 100 + ret
else sum (ret+i) (i+1) in
sum 0 1
這意味着它根本不會評估列表。 不幸的是,在某些情況下,當生成程序的最終結果時,編譯器無法知道某個值將始終位於NF中。 然后,浪費時間和RAM使其保持deepseq
(形成deepseq
東西deepseq
):從一開始就更好地進行deepseq
。 否則您的編譯器可能會出現性能錯誤,因此您必須使用seq
或deepseq
幫助它。 探查器將告訴您代碼的哪些部分運行緩慢。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.