On Wed, Oct 21, 2009 at 9:44 PM, Wouter Swierstra <w...@cs.nott.ac.uk> wrote: > The only change with the previous version has been to add irrefutable > patterns to several function definitions. This is rather delicate design > decision: too many irrefutable patterns could result in thunks not being > evaluated; too few irrefutable patterns could cause your functions diverge. > As a rule of thumb I've chosen only to use irrefutable patterns in functions > that produce streams from streams. The operations that observe finite > information (a prefix, the element at index i, etc.) do not have have > irrefutable patterns and force evaluation to weak head normal form.
Hi Wouter, I have two questions: 1) What's the difference between your: "tail ~(Cons _ xs) = xs" and the more simple: "tailStrict (Cons _ xs) = xs" ? I know they're desugared to: "tail ys = let Cons _ xs = ys in xs" and: "tailStrict ys = case ys of Cons _ xs -> xs" respectively. But aren't they operationally the same: "tail undefined = undefined" and: "tailStrict undefined = undefined" 2) Why don't you also use an irrefutable pattern in "take"? "take" is now defined as: take :: Int -> Stream a -> [a] take n (Cons x xs) | n == 0 = [] | n > 0 = x : (take (n - 1) xs) | otherwise = error "Stream.take: negative argument." so "take 0 undefined = undefined" while: takeLazy :: Int -> Stream a -> [a] takeLazy n ~(Cons x xs) | n == 0 = [] | n > 0 = x : (takeLazy (n - 1) xs) | otherwise = error "Stream.take: negative argument." "takeLazy 0 undefined = []" regards, Bas _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe