[Haskell] lazy constructors
Serge D. Mechveliani
mechvel at botik.ru
Wed Oct 13 01:59:37 EDT 2004
Dear Haskellers,
I try to organize a `lazy' output in my program, so that the
data are accumulated, step by step in a pair
(String, String)
(a contrived simplified example).
And the first component is a `story' to be printed out in a `lazy'
manner, the first steps need to print without waiting for the whole
data field to be ready.
If the program returns String, then I can arrange this.
But with (String, String), I do not know how to do.
And in the real progam, it is a more complex labeled record, carried
along through the program.
Probably, the obstackle is in the very Haskell language.
Consider a simple example:
---------------------------------------------------------------
bottomStr :: String
bottomStr = let xs = xs in xs
bottomSPair :: (String, String)
bottomSPair = let p = p in p
bound = 10^8 :: Int -- some large number
f1, f2, g1, g2 :: Char
f1 = head ('a' : (if last [1 .. bound] > 0 then "b" else "c"))
f2 = head ('a' : bottomStr)
g1 = head $ fst $ addToSPair 'a'
(if last [1 .. bound] > 0 then ("b", "") else ("c", ""))
g2 = head $ fst $ addToSPair 'a' bottomSPair
addToSPair :: Char -> (String, String) -> (String, String)
addToSPair c (xs, ys ) = (c:xs, ys )
main = putStr [ f1, '\n' ]
-- f2
-- g1, g2
---------------------------------------------------------------
g1 is similar to f1, g2 similar to f2.
f1 and f2 are evaluated immediately to 'a';
g1 evaluates to 'a' after a long computation;
g2 evaluates to Fail: <<loop>>
As g2 is similar to f2, should it have a value 'a' ?
In
head $ fst $ addToSPair 'a' bottomSPair
bottomSPair is of type (String, String).
addToSPair is declared as returning (String, String).
Hence, the complier knows ab initio that after addToSPair
the result is of kind
('a': _, _) :: (String, String)
Hence, applying further head $ fst yields 'a'.
This is in the air of a `lazy' computation.
In a more clear presentation, the computation should (?) be
head $ fst $ addToSPair 'a' bottomSPair
=
head $ fst $ addToSPair 'a' (bottomStr, bottomStr)
=
head $ fst (`a':bottomStr, bottomStr)
=
head (`a':bottomStr)
=
'a'
So, similarly as
head ('a' : bottomStr) = 'a', (1)
it should be
head $ fst $ addToSPair 'a' bottomSPair = 'a' (2)
Probably, Haskell-98 does not put so. Right?
Question 1
----------
What may be the consequences for the language
(let us call it HCLazy) if it treats the data constructors like in
(2), like more `lazy' ones?
For example, fst (bottom :: (a,b)) = (bottom :: a)
Question 2
----------
How to arrange the above `lazy' output?
The whole result story is ready in several hours, or days,
and each step should be displayed immediately as it is ready.
So far, I see no other way as to compile the program together with
the Trace library, inserting there the calls
\ step ... -> trace (show step) $ ...
(?)
Thank you in advance for the explanations.
Copy, please, the answer to mechvel at botik.ru
-----------------
Serge Mechveliani
mechvel at botik.ru
More information about the Haskell
mailing list