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 _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe