
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