Thanks Mark, On Friday 11 January 2002 7:41 am, Mark P Jones wrote:
Denotationally, the two expressions are the same. (In other words, they both produce the same value.) But the example above shows an operational difference in some implementation. (As far as I can tell, however, nothing in the language definition either guarantees or prevents such behavior.)
Ah, now I see the issue seems to be closeley related to full lazy lambda lifting. Given.. f = \x -> <blah> x where <blah> has no free occurences of x, then I thought the compiler would reduce this immediately to f = <blah> Full lazy lambda lifting would give something like this.. b = <blah> f = \x -> b x But this still requires, the (\x -> b x) to be reduced to b to get.. b = <blah> f = b (and hence f = <blah>) Do (should) Haskell compilers do this, as a general rule? It all seems bit vague to me :-(
Personally, I'd tend to let considerations other than performance affect my choice.
For example, if I'd declared f :: a -> String -> [(a, String)] then I might use a definition like:
f x s = [(x, s)] -- two parameters in the type, so two -- parameters in the definition
But if the type signature was f :: a -> Parser a and if I'd defined:
type Parser a = String -> [(a, String)]
then I'd write the definition of f in the form:
f x = \s -> [(x, s)] -- f is a function of one argument -- that returns a parser as a result.
Funnily enough, it was the issue of parsing which prompted me to ask the question.. I guess most people would write.. myParser = <sexy_combinator_expression> and not.. myParser tokens = (<sexy_combinator_expression>) tokens But I wasn't too sure whether the two forms would give equally efficient code (and if not then which one was 'best'). It seems the answer depends on the compiler implementation and/or the level of optimisation selected. Regards -- Adrian Hey