它們在嚴格性上有所不同。假設我們重命名它們:
> let addVectorsStrict (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)
> let addVectorsLazy a b = (fst a + fst b, snd a + snd b)
addVectorsStrict undefined undefined
是undefined
是一旦外(,)
構造的結果是需要進行-the模式匹配:
> case addVectorsStrict (error "A") (error "B") of (_, _) ->()
*** Exception: A
但addVectorsLazy undefined undefined
是(undefined, undefined)
-the模式匹配推遲到結果的元素之一被要求。
> case addVectorsLazy (error "A") (error "B") of (_, _) ->()
()
基本上,addVectorsLazy
總是返回一個元組,其中,所述元件可以是未計算的。 addVectorsStrict
可能不會返回。你也可以使用一個懶惰的模式匹配得到的addVectorsLazy
效果:
> let addVectorsAlsoLazy ~(x1, y1) ~(x2, y2) = (x1 + x2, y1 + y2)
> case addVectorsAlsoLazy (error "A") (error "B") of (_, _) ->()
()
爲了更好地瞭解評估順序的,你可以使用Debug.Trace.trace
觀察它:
addVectors
(trace "first tuple evaluated"
(trace "x1 evaluated" 1, trace "y1 evaluated" 2))
(trace "second tuple evaluated"
(trace "x2 evaluated" 3, trace "y2 evaluated" 4))
基本的是要記住的在Haskell中的評估是它使用case
和函數方程(其中去掉了case
)進行模式匹配。
它沒有多大關係在這種情況下,但你可以懶洋洋地寫你的功能,以避免昂貴的評估計算,如果是從來不需要他們的結果,或嚴格避免的thunk的開銷,如果你知道一些結果總是被需要。
在一般情況下,這是一個好主意,使你的數據結構嚴格的領域,除非你需要他們偷懶,讓您功能懶惰,除非你需要他們嚴格。在這裏,你可以製作一個嚴格的對類型來表示你的矢量:
data Vector a = Vector !a !a
嗯,這只是一種不同的風格定義相同的東西。你的問題到底是什麼? – leftaroundabout
作爲一般建議,我建議儘可能地學習使用模式匹配,至少在初學者級別。'fst,snd'的替代方法是可以的,但是在這裏,我看到太多的初學者使用危險的函數,比如'head,tail,fromJust',當模式匹配更安全時,這往往會導致崩潰,特別是當使用'-Wall'打開警告(強烈推薦)。 – chi