[Haskell-cafe] RE: [Haskell] lazy constructors
[I think this thread would be more appropriate on haskell-café, so I'm redirecting it] | addToSPair :: Char - (String, String) - (String, String) | addToSPairc (xs, ys) = (c:xs, ys) | | --- | | 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 Try using lazy pattern matching, thus addToSPair :: Char - (String, String) - (String, String) addToSPairc ~(xs, ys) = (c:xs, ys) The only change is the ~ in the defn of addToSPair. Now g2 will have value 'a'. Simon ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] RE: [Haskell] lazy constructors
addToSPairc ~(xs, ys) =3D (c:xs, ys) I thought pattern bindings had an implicit ~? Keean. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: [Haskell] lazy constructors
On Wed, Oct 13, 2004 at 09:23:43AM +0100, MR K P SCHUPKE wrote: You can only return a list of pair's lazily, not a pair of lists. If the two strings are independant, then generate each in a separate function, and pair off the results lazily. No, I have several labeled fields in a record, which are very dependent. As people teach, the costruct of ~(..,..) helps for the Pair. Maybe, the labeled record can also be handled ... - Serge Mechveliani [EMAIL PROTECTED] ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: [Haskell] lazy constructors
addToSPair :: Char - (String, String) - (String, String) What about: addToSPair :: Char - String - String - (String,String) so that the pattern match is: addToSPair c xs ys = (c:xs,ys) This is irrefutable? Keean. ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: [Haskell] lazy constructors
Serge D. Mechveliani wrote: As the types are resolved before the computation, as the above program shows, how can addToSPair expect anything besides a string pair? Why tilda is not a default? Haskell pairs are lifted, meaning that they also include an extra value (bottom) which doesn't match (x,y). Not everyone is convinced that this is a good idea, but it's the way things are at present. The only doubt may be the matching of (xs, ys) against bottom :: (String, String) Is not this natural to have a result as (bottom :: String, bottom :: String) -- = xs = ys and compute further? Possibly in this case, yes. But not in general, since there might be other data constructors also. What will occur if all the Haskell programmers set `~' before each data constructor in each pattern in their existing programs? Things won't work as you'd expect. For example, if you defined null :: [a] - Bool null list = case list of ~(x:xs) - False ~[] - True you would find that (null []) is False, not True, because the first pattern matches irrefutably. Pattern matching needs to be strict so that case statements like this work sensibly. As the types are recognized before the computation, the programs will remain safe and will become considerably faster. For example, the above program of g1 becomes a billion times faster. I wonder. Actually using irrefutable patterns tends to make a program slower, not faster, because it makes the program less strict. Good questions! -- Ben ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: [Haskell] lazy constructors
I thank Jeremy Gibbons, Ben Rudiak-Gould, and other people, for their helpful explanations. On Wed, Oct 13, 2004 at 02:34:55PM +0100, Ben Rudiak-Gould wrote: Serge D. Mechveliani wrote: As the types are resolved before the computation, as the above program shows, how can addToSPair expect anything besides a string pair? Why tilda is not a default? Haskell pairs are lifted, meaning that they also include an extra value (bottom) which doesn't match (x,y). Not everyone is convinced that this is a good idea, but it's the way things are at present. The only doubt may be the matching of (xs, ys) against bottom :: (String, String) Is not this natural to have a result as (bottom :: String, bottom :: String) -- = xs = ys and compute further? Possibly in this case, yes. But not in general, since there might be other data constructors also. What will occur if all the Haskell programmers set `~' before each data constructor in each pattern in their existing programs? Things won't work as you'd expect. For example, if you defined null :: [a] - Bool null list = case list of ~(x:xs) - False ~[] - True I am sorry. Of course, I meant the functions in which it was set initially only a single pattern. People often write such. As the types are recognized before the computation, the programs will remain safe and will become considerably faster. For example, the above program of g1 becomes a billion times faster. I wonder. Actually using irrefutable patterns tends to make a program slower, not faster, because it makes the program less strict. Probably, unneeded strictness bites more seriousely than unneeded laziness. What I fear of is the following hidden slow down. Suppose that such a function (as the above addToPair) updates a value of type ([a], [b]) in a loop. And consider a client function let p = form_list_pair_via_addToPair ... ... h = g p p ... in if (take 3 $ fst p) == abc then ... else ... The value of p is used in several places, the whole program looks natural. The programmer relies on that (take 3 $ fst p) computes `lazily'. In fact, I like to rely on the `laziness' and think that it makes the programs more clear. Otherwise, one could program, say, in ML. Now, if one does not guess to set tilda in addToPair, the whole program becomes slower somewhat in (length xs)/3 times! Here xs is a list accumulated in the first component of the form_list_pair_via_addToPair result. If length xs = 900, then the slow down in 300 times. Is there any systematic approach allowing to avoid a performance adventure like this? May the compiler help, may it issue a warning? And maybe, there are other sources of the slow downs due to unneeded strictness. Regards, - Serge Mechveliani [EMAIL PROTECTED] ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe