3 回答

TA貢獻1805條經驗 獲得超10個贊
這是一個嚴格的聲明?;旧希@意味著在創建數據結構值時,必須將其評估為所謂的“弱頭范式”。讓我們看一個示例,以便我們可以看到這意味著什么:
data Foo = Foo Int Int !Int !(Maybe Int)
f = Foo (2+2) (3+3) (4+4) (Just (5+5))
f上面的函數在被求值時將返回“ thunk”:即,執行以確定其值的代碼。到那時,Foo甚至還不存在,僅存在代碼。
但是在某些時候,可能有人會嘗試通過模式匹配來查看其中的內容:
case f of
Foo 0 _ _ _ -> "first arg is zero"
_ -> "first arge is something else"
這將執行足夠的代碼來執行所需的工作,僅此而已。因此它將創建具有四個參數的Foo(因為如果沒有它,您將無法在其中查看內容)。首先,因為我們正在測試它,所以我們需要一直評估到4,直到我們發現它不匹配。
第二個不需要評估,因為我們沒有測試它。因此,6我們不會將代碼存儲在該內存位置中,而是將其存儲以用于以后的評估(3+3)。僅當有人看時,它就會變成6。
但是,第三個參數!在其前面,因此必須進行嚴格評估:(4+4)已執行并8存儲在該內存位置。
第四個參數也被嚴格評估。但是,這里有些棘手:我們沒有完全評估,只是評估了弱勢的正常頭型。這意味著我們要弄清楚是什么Nothing還是Just某種東西,并將其存儲起來,但是我們走得更遠了。這意味著我們Just 10實際上不是存儲而是Just (5+5)保留其中的雜物未被評估。要知道這一點很重要,盡管我認為這的所有含義都超出了此問題的范圍。
如果啟用BangPatterns語言擴展,則可以用相同的方式注釋函數參數:
f x !y = x*y
f (1+1) (2+2)會歸還笨拙的(1+1)*4。

TA貢獻1784條經驗 獲得超8個贊
我相信這是嚴格的注解。
Haskell是一種純粹且懶惰的函數式語言,但有時懶惰的開銷可能過多或浪費。因此,為了解決這個問題,您可以要求編譯器完全評估函數的參數,而不是解析亂碼。
添加回答
舉報