From Hoogle:
Query: (:[]) Error: unexpected ":" expecting "#", ",", "forall", "(", "[", "!" or ")" Bad symbol Prelude> let h = length . (:[]) . head Prelude> h undefined 1 Prelude> :t (:[]) (:[]) :: a -> [a] Prelude> h [] 1 <======== this comes as a surprise Prelude> Are you saying: [ head x ] -> [ *thunk* ] and length [ *thunk* ] -> 1, independent of what *thunk* is, even head [], i.e., *thunk* never needs be evaluated? Michael --- On Sat, 7/31/10, Ben Millwood <haskell@benmachine.co.uk> wrote: From: Ben Millwood <haskell@benmachine.co.uk> Subject: Re: [Haskell-cafe] Laziness question To: "michael rice" <nowgate@yahoo.com> Cc: haskell-cafe@haskell.org Date: Saturday, July 31, 2010, 1:47 PM On Sat, Jul 31, 2010 at 5:59 PM, michael rice <nowgate@yahoo.com> wrote:
OK, in f, *length* already knows it's argument is a list.
In g, *length* doesn't know what's inside the parens, extra evaluation there. So g is already ahead before we get to what's inside the [] and ().
According to the types, we already know both are lists. The question is, of course, what kind of list.
But since both still have eval x to *thunk* : *thunk*, g evaluates "to a deeper level?"
Michael
I think this question is being quite sneaky. The use of head and tail is pretty much irrelevant. Try the pointfree versions: f = length . (:[]) . head g = length . tail and see if that helps you see why f is lazier than g.