
Thanks, that clarifies things a lot; I must improve my laziness-fu!
(to Belka: Also, lazy matching may be performed as .... fix
(\(~(aa,bb)) -> ...) - the tilde does the trick)
2009/1/29 Ryan Ingram
On Thu, Jan 29, 2009 at 12:44 AM, Eugene Kirpichov
wrote: With the Y combinator, the code becomes as follows:
f = \somedata1 somedata2 -> fst $ fix (\(aa,bb) -> (AA somedata1 bb, BB somedata2 aa))
I tried to prove to myself that the structure really turns out cyclic, but games with reallyUnsafePtrEquality# didn't lead to success; that's why it's "reallyUnsafe" :-/
Your definition with "fix" isn't lazy enough, so it goes into an infinite loop. You need to match lazily on the pair; here's a better body for "fix":
fix (\p -> (AA somedata1 $ snd p, BB somedata2 $ fst p))
To prove that the structure really turns out cyclic, you can use Debug.Trace:
import Debug.Trace (trace) import Data.Function (fix)
data AA = AA Int BB deriving Show data BB = BB Int AA deriving Show
f = \data1 data2 -> fst $ fix $ \p -> (trace "eval_aa" $ AA data1 $ snd p, trace "eval_bb" $ BB data2 $ fst p)
sumAA 0 _ = 0 sumAA n (AA v bb) = trace "sumAA" (v + sumBB (n-1) bb) sumBB 0 _ = 0 sumBB n (BB v aa) = trace "sumBB" (v + sumAA (n-1) aa)
main = print $ sumAA 10 $ f 1 2
*Main> main eval_aa sumAA eval_bb sumBB sumAA sumBB sumAA sumBB sumAA sumBB sumAA sumBB 15
-- ryan