let (d,k) = (g x y, h x d) ..
Dear Haskellers, Once I wrote a function f' :: Int -> Int -> Int -> (Int, Int) f' n m l = let (d,k) = (gcd n m, quot n d) in (k, l*k) (the simplified version of real program), placing erroneousely d to both parts of the pattern matching (d,k) = ... The intended program was f n m l = let {d = gcd n m; k = quot n d} in (k, l*k) But f' gives the intended results, at least in the GHC implementation. So that I did not notice the `error' for a long time. Is really the Haskell pattern matching semantic so that f and f' are equivalent ? Is it an occasional implementation feature that hide the `error'? Thank you in advance for the explanation. Answer, please, to mechvel@botik.ru ----------------- Serge Mechveliani mechvel@botik.ru
On Fri, 27 Jun 2003 12:22:46 +0400 "Serge D. Mechveliani" <mechvel@botik.ru> wrote:
Dear Haskellers,
Once I wrote a function
f' :: Int -> Int -> Int -> (Int, Int)
f' n m l = let (d,k) = (gcd n m, quot n d) in (k, l*k)
(the simplified version of real program), placing erroneousely d to both parts of the pattern matching (d,k) = ...
The intended program was
f n m l = let {d = gcd n m; k = quot n d} in (k, l*k)
But f' gives the intended results, at least in the GHC implementation. So that I did not notice the `error' for a long time.
Is really the Haskell pattern matching semantic so that f and f' are equivalent ?
Haskell is a lazy language. You can define values in terms of themselves (with emphasis on -values-). Here's a (relatively) simple example of doing this for more and (some) explanation see http://haskell.org/hawiki/TyingTheKnot. -- list_rep_min: replace list with it's minimum value in one pass list_rep_min l = result where (result,mini) = lrm l mini lrm [x] m = ([m],x) lrm (x:xs) m = (m:ms,x `min` m') where (ms,m') = lrm xs m
Is it an occasional implementation feature that hide the `error'?
No. It's a language feature, though it does cause problems. My advice is simply to avoid shadowing (local) variables. I am usually pretty good about following it, but one particular time I didn't, I ended up with a function that seemed 'mysteriously' broken. I felt pretty stupid when I finally noticed what it was. Oddly, enough I was actually thinking that I was shadowing too much as I wrote the code.
Serge D. Mechveliani wrote:
f' n m l = let (d,k) = (gcd n m, quot n d) in (k, l*k) ...
The intended program was
f n m l = let {d = gcd n m; k = quot n d} in (k, l*k)
But f' gives the intended results, at least in the GHC implementation. So that I did not notice the `error' for a long time.
Is really the Haskell pattern matching semantic so that f and f' are equivalent ?
But, in a lazy language it is the same, the let defs. are processed colaterally, the only difference is the (possibly optimized away) creation of the intermediate tuple (d,k). Jerzy Karczmarczuk
participants (3)
-
Derek Elkins -
Jerzy Karczmarczuk -
Serge D. Mechveliani