[Haskell-cafe] Question on leazy evaluation

Tomasz Zielonka tomasz.zielonka at gmail.com
Fri Mar 25 09:53:56 EST 2005


On Fri, Mar 25, 2005 at 03:13:48PM +0100, Pierre Barbier de Reuille wrote:
> plus :: Fct a b -> Fct a b -> Fct a b
> plus (Fct f1) (Fct f2) = Fct ( \ a -> (f1 a) ++ (f2 a) )
> 
> For some reason, this function does not use leazy evaluation ! I can 
> test it using :
> 
> test_fct :: Fct Int Int
> test_fct = Fct( \ i -> [i] )
> 
> value = head $ apply (foldr plus test_fct $ repeat test_fct) 12
> 
> ... trying to get "value" does not terminate !

That's because you pattern match on (Fct f2) in plus. If Fct is defined
with 'data', this causes the second argument of plus to be evaluated.

> But if I change the type declaration into :
> 
> newtype Fct s a = Fct (s -> [a])
> 
> ... it works ! The "plus" function uses leazy evaluation and "value" can 
> be computed.

If Fct is defined with 'newtype', it doesn't cause evaluation, because
Fct is a kind of virtual / non-existent / zero-cost data constructor,
so there is nothing to evaluate.

Try these definitions:

    plus (Fct f1) ~(Fct f2) = Fct ( \ a -> (f1 a) ++ (f2 a) )

    plus (Fct f1) f2 = Fct ( \ a -> (f1 a) ++ (apply f2 a) )

The first uses an irrefutable pattern, the second doesn't pattern
match on Fct in the second argument.

Best regards
Tomasz


More information about the Haskell-Cafe mailing list