Re: Division, remainder, and rounding functions
|Your definition of divFloorRem (and probably divCeilingRem as well) |doesn't seem to be quite right, because I end up with | (-4) `mod` (-3) == -4 |because divTruncateRem (-4) (-3) is (1,-1). | |The condition in the "if" should be something like | signum r == -signum d |rather than r0. (Something like this is in the definition of |`mod` on page 89 in 1.2beta.) | |Stefan Kahrs Right, thanks. I've committed the error of forgetting that the divisor can be negative. I did the rounding methods first, where the "divisor" is 1, and then did the division methods by (incorrect!) analogy. You'd think that after n years of struggling with with definitions like these, I'd be able to get them right! So, as you say, this can be fixed thus: divFloorRem n d = if signum r == - signum d then (q-1, r+d) else qr where qr@(q,r) = divTruncateRem n d divCeilingRem n d = if signum r == signum d then (q+1, r-d) else qr where qr@(q,r) = divTruncateRem n d Another way: divFloorRem n d = if r 0 then (q-1, r+d) else qr where qr@(q,r) = divTruncateRem n' d' (n', d') = if d 0 then ((-n),(-d)) else (n,d) divCeilingRem n d = if r 0 then (q+1, r-d) else qr where qr@(q,r) = divTruncateRem n' d' (n', d') = if d 0 then ((-n),(-d)) else (n,d) --Joe
Re: take and drop
Simon, For some reason, I can't find the relevant messages about this, but my recollection is that during the 1.1 revision (maybe earlier) the Glaswegians discussed length and friends and recommended that I do just what was done: making the result of length specifically Int, but leaving take, drop, splitAt, (!!) (I think that's all of them) as (Integral a) = ... . The reason is that length alone manufactures a number with a type that doesn't depend on an argument type, and thus is possible trouble for overloading ambiguity. --Joe To: Joe Fasel [EMAIL PROTECTED] Cc: haskell Subject: take and drop Date: Fri, 14 Feb 92 15:50:32 + From: Simon L Peyton Jones simonpj Sender: haskell-request Joe A prelude question: The function length returns an Int. Shouldn't take and drop take an Int?
Re: The Great Integer Division Controversy
Folks, There was a small omission in the Integral declaration I just sent; the first line should be class (Real a, Ix a) = Integral a where Similarly, the Real declaration begins class (Num a, Enum a) = Real a where This is from Mikael Rittri's proposal. --Joe
Re: unzip
|The new unzip* functions in 1.2 are not suitable for unzipping an |infinite list. (What Phil called "A splitting headache".) |Is this deliberate or a mistake? I'd like them to be lazier. A mistake, thanks. I've fixed it. --Joe "I hate ^-patterns" Fasel
Re: The Great Integer Division Controversy
Folks, Kent has pointed out to me that the Haskell's use of `div` for truncating, as opposed to flooring, division is incompatible with both SML and Miranda, whereas neither Scheme nor Common Lisp have a function by that name. (Scheme calls it "quotient".) I am willing to change `div` to `quo` and `dvf` to `div` if there is consensus. Are there opinions? (Time is short.) --Joe
Re: Enum bugs in 1.2.beta
|At the last minute, I have found some Enum bugs in 1.2.beta. |As I don't know if they have been fixed in 1.2.gamma, which |I guess was circulated yesterday, here they are: Thanks, Mikael. | 1) According to the specification (section 3.9), the | value of | | [ 7, 7 .. 3 ] | | is the infinite list [ 7, 7, 7, 7,...], but the | default definition of enumFromThenTo (pp. 30 and 91) | gives the value | | takeWhile (= 3) enumFromThen 7 7 | | which is the empty list! I think it's section 3.9 that's wrong here. Can we please change the two occurences of "the increment is positive" to "the increment is nonnegative" and then clarify which cases lead to an infinite list? | 2) Similarly, the value of | | ['z', 'y' .. 'a'] | | should be the alphabete in reverse order, but according to | the Enum instance of Char (p. 92), we get | | takeWhile (= 'a') (map chr [ord 'z', ord 'y' .. ord maxChar]) == | takeWhile (= 'a') (map chr []) == | [], | | i.e, also the empty list. | | Suggested fixes: | | 1) The default definition of enumFromThenTo (pp. 30 and 91) | should be: | | enumFromThenTo n n' m | n n' = takeWhile (= m) (enumFromThen n n') | | n n' = takeWhile (= m) (enumFromThen n n') | | n == n' = repeat n | | otherwise = error "enumFromThenTo{PreludeCore}: \ | \no ordering relation" See above. I don't think this is what we really want. The sequence should always terminate when the increment is nonnegative and the value exceeds the limit or the increment is negative and the value is less than the limit. (This is a shortcoming of this notation; there is a real virtue in having to say "upTo" or "downTo" or some such.) (Note: The otherwise case isn't really necessary. Incrementing or decrementing on a partial order aren't well-defined anyway.) | 2) The instance Enum Char (p. 92) should read: | | enumFromThen c c' | c c' = map chr [ord c, ord c' .. ord maxChar] | | c c' = map chr [ord c, ord c' .. ord minChar] | | otherwise = repeat c I think this should then be enumFromThen c c' = map chr [ord c, ord c' .. ord (if c' c then minChar else maxChar)] --Joe
Re: The last (sic) bug in the Prelude
Let me try that again: rationalToRealFloat:: (RealFloat a) = Rational - a rationalToRealFloat x = x' where x'= f e f e = if e' == e then y else f e' where y = encodeFloat (round (x * (b%1)::(-e)) e (_,e') = decodeFloat y (_,e) = decodeFloat (fromInteger (numerator x) `asTypeOf` x' / fromInteger (denominator x)) b = floatRadix x'
Re: The last (sic) bug in the Prelude
Folks, Here's an attempt at rationalToRealFloat (formerly known as rationalToFloating): rationalToRealFloat:: (RealFloat a) = Rational - a rationalToRealFloat x = x' where x'= f e f e = if e' == e then y else f e' where y = encodeFloat (round (x * (1 % b::e))) e (_,e') = decodeFloat y (_,e) = decodeFloat (fromInteger (numerator x) `asTypeOf` x' / fromInteger (denominator x)) b = floatRadix x' Again, if anybody has a better idea, I would certainly like to hear about it. Thanks. --Joe
Re: I/O
| Tonny Davie says | | Evan Ireland says | | As Nigel and I have | pointed out to numerous people (including Haskell committee members), the | statement that stream I/O cannot be efficiently emulated by continuation I/O i | true only if the continuation model being used is lacking in certain request | types (i.e. references/assignment as in Tui or coroutines as in Hope+C). | | I thought Paul Hudak's seminal paper 'On the Expressiveness of Purely Functional | I/O Systems' had shown that stream I/O was COMPLETELY equivalent to continuation | I/O. Or is the emphasis above to be taken to be on the word 'efficiently'? Regarding efficiency, can someone comment on whether there is any difference between the stream and continuation models in the effect on parallelism? --Joe
Re: Array Indexing
| ! It is the responsibility of the programmer to enforce bounds | ! checking when required in non-derived instances of class @Ix@. | ! An implementation is not required to check that an index | ! lies within the bounds of an array when accessing that array. | | The above is fine by me, but here is a more concise wording, which may | do as well. | | ! It is the responsibility of the programmer to enforce bounds | ! checking in non-derived instances of class @Ix@, if it is desired. | | Cheers, -- P This sounds fine to me. Maybe I should put bounds checks in the Ix instance declarations for Integer, Int, and Char in PreludeCore. --Joe
Re: N.K.Anil
| paul Hudak in his 'gentle introduction to haskell" says that a where clause | is allowed only at the top level of a set of equations or case expression. | | So you cannot declare | let | f x = z / y where z = x + y | in | | I do not know the reason why this restriction has been put. | I see the above definition perfectly alright. | Can anybody send me the reason for the above restriction. | | -- [EMAIL PROTECTED] The wording "top level" was perhaps unfortunate. Your example is, in fact, perfectly all right. The point is that z / y where z = x + y is not an expression. Although f x = z / y where z = x + y is equivalent to f x = let z = x + y in z / y , f x = (let z = x + y in z / y) + 1 is acceptable, whereas f x = (z / y where z = x + y) + 1 is syntactically incorrect. Thus, one often has a choice of using a "let" or a "where" for supporting definitions, but "let" cannot scope over multiple guarded righthand sides or cases, and "where" cannot be used in a nested expression. On a slightly different subject, as a matter of taste and readability, I recommend avoiding deeply nested definitions in general and using "where" clauses except where a binding _must_ scope over a subexpression (as arises, for example, in continuation-passing style). For example, the last example above is probably better rendered as f x = z / y + 1 where z = x + y or perhaps f x = w + 1 where w = z / y z = x + y (Others may disagree.) --Joe
Re: relative precedence of ! and function application
| Array notation conventions aside, I think the simple rule that normal | application has higher precedence than infix application is a Big Win. | Perhaps the committee should have introduced special syntax for arrays, | but that was simply not palatable to most of the members, even though | it was for lists. The problem was that all the brackets were taken for other purposes. We could have used multicharacter brackets, such as f x[\i\] but this strikes me as even more painful, or at least, not worth the complication of the special syntax. --Joe
Re: relative precedence of ! and function application
|Given that layout has been used in Miranda, Haskell, etc., to determine |when one thing ends and another begins, it might be worth trying the |same idea within expressions. The suggestion is that any subexpression |that contains no white space but is surrounded by white space has |implied parentheses around it. Hence | |f x!i would parse as f (x!i) | |This would make functions definitions with pattern matching easier too. |For example, we could write: | |sum x:xs = x + sum xs | |instead of | |sum (x:xs) = x + sum xs | |I'm not completely convinced myself, but thought it was an idea worth |floating. | |Warren Mark Wells reported, in a paper in SIGPLAN Notices a few years ago, using a similar scheme in the language Modcap. (A funny thing about this paper is that he attributes the idea to me, and I don't recall suggesting any such thing!) In, Modcap, I believe, the notion was that white space surrounding an operator modified its syntactic precedence, so that an operator with space around it had a lower precedence than any without space. Mark also noted that the scheme could be extended to allow larger amounts of white space to imply yet lower precedence levels, but they didn't implement this extension and weren't convinced of its benefits. Frankly, the idea frightens me (which is why I was a bit perturbed at having it attributed to me :-), but Warren has a good point about its being consistent with layout. By the way, Mark reported that their experience with this trick was quite positive. --Joe
Re: Haskell I/O
|From: "Shah Namrata Abhaykumar" [EMAIL PROTECTED] |Subject: Haskell I/O | |I am trying to understand I/O in haskell. I have trouble understanding |how it is referentially transperant ? |Consider that main is, | |main resps = [req1,req2,req3,req4] | where req1 = .. | req2 = (tl resps) | req3 = (tl resps) | req4 = .. | |As, req1,..,req4 are all evaluated in the environment with a binding for |resps, both (tl resps) in req2 and req3 should evaluate to same |expression (referential transperancy). But when req2 is evaluted, |resps = [response_to_request1] and when req3 is evaluated, |resps = [response_to_request1, response_to_request2]. No, the list resps does not change, although it is evaluated lazily. |Hence, (tl resps) in req2 and req3 donot evaluate to the same value. |Isn't referential transperancy lost ? In other words, the binding |for resps keep on changing i.e. there is some side effect occuring |somewhere. There are no side effects in the Haskell program, which is a pure function from streams of responses to streams of requests. We may, however, regard the operating system that interprets the requests and delivers the responses as acting on the requests in order and producing effects on the file system. | This is the picture that I have drawn after reading Haskell |I/O. I may be wrong somewhere. Correct me if I am wrong. | |-Namrata Shah |([EMAIL PROTECTED]) I hope my explanation has helped. Cheers, --Joe
Re: a note on the Haskerl extension to Haskell [long]
I know it's late in the day for most of you (or already tomorrow), but a colleague of mine here at Los Alamos has made a suggestion I just have to pass along: Will Partain writes |We might then match against a list of Foos (type "[Foo]") as follows: | |case expr of | /^{Foo1 _ {4}}({Foo2 _ _})+{Foo1 _ _}?.$/ - ... Another thing we really ought to do to demonstrate that we've arrived and Haskell is good for real applications is to hold an obfuscated Haskell contest. I volunteer to moderate. --Joe
Re: a note on the Haskerl extension to Haskell
David Wakeling writes |Yes, Certainly. Here at York we have a small electrical hoist in one of the |Departmental stairwells which is used for lifting expensive and delicate |equipment onto the upper floor of the building. As part of an experiment in |real time functional programming, I wrote a Haskell program to control this |hoist. It proved to be a tricky exercise: the hoist is controlled by a number |of registers, and reading and writing these registers in the correct order |with the correct values proved to be a royal pain. Indeed, . . . When someone in the UK uses a phrase like this, I'm never sure whether the usage is literal or figurative. Tell me , Dave, is this because your lift project has some connection with H.M. royal shaft I heard about a couple of years ago? (It seems to me the phrase was used in connection with the proposed poll tax---I mean "Community Charge"---but I never was able to work out what this had to do with lifts.) --Joe
Re: Layout
| Oh ye Haskell wizards. Is the following program syntactically legal | or not? | | x = leta = let { b=1; | c=2 | } in 3 | in 4 | | I.e. is the layout rule from an outer scope in effect even inside | explicit brackets? Obviously, this needs clarification. There would seem to be three possibilities: 1) Layout from an outer scope applies even within explicit brackets. 2) Layout can be used in a nested scope inside explicit brackets, but indentations from outside the brackets do not apply. 3) Layout is never in effect within explicit brackets. I favor (3) for its simplicity, although (2) is also sensible. (1) seems like a bad idea. | Here's another | | x = let a = let | in 3 | in 4 | | OK, what happens? First we insert an lcurl after the first let and | remember the indentation (8). Then the second let will get an lcurl | at indentation 3 (position of in). But 3 is less than 8 so there also be | an rcurl from the first let. The last in will have an rcurl inserted because | otherwise we would have a syntax error. So we get | | x = let { a = let | {}in 3 | }in 4 | | This is a correct program, but the curls in the empty let were not inserted | by matching constructs!! | | | -- Lennart Niklas I think this could be clarified by a slight rewording of the layout rules: Rather than saying that a layout indentation is established by the first token other than { following one of the herald keywords, say that anywhere the grammar has { decls } a layout indentation is established by the first token of decls , if any, in the absence of a preceding {. Thus, in the above example, there is no layout for the inner let. Of course, this rule is no longer purely lexical, but that is the case with inserted }s anyway. --Joe
Re: Haskell Report 1.2
|Joe writes: | [My simple syntax for LHSes] doesn't cover things like | | (f .* g) x y = f (g x y) | |and proposes a syntax which is the same as my simple proposal, |but covers exactly this also. | | lhs ::= (var | @(@ ilhs @)@) apat+ | | ilhs | | pat | | ilhs ::= pat{i+1} varop(n,i) pat{i+1} | | lpat{i} varop(l,i) pat{i+1} | | pat{i+1} varop(r,i) rpat{i} | |I don't see any major problem with your proposal once the (n+k) |ambiguity is resolved. And it is much easier to understand |than the present syntax. Good. Let me add a disclaimer, though. This appears to me still to be LR-parseable (except for the genuine ambiguity), because in the absence of arbitrary parenthesization, a finite lookahead is sufficient to distinguish, for example, (n+1) x = from (n+1) `op` x = but I haven't run anything through a parser generator. |I could also accept lhs = pat = exp (now that is simple!). It's |a bit odd to think of | | x * f y = e | |as a semantic error, but that's largely a question of error reporting, |I suppose. right. | 2) A binding within an instance declaration cannot be a | pattern binding. Elsewhere, the ambiguity is resolved | as an n+k binding. | |This seems rather ad-hoc. Why are instance declarations special? | | class Integral a = Foo a where | v :: a | | instance Foo Int where | (v+1) = ... Quite right. I didn't say this very well. Here's another try: We _could_ limit the interpretation of of the ambiguity as a binding of (+) to instance declarations for a class with + in its signature (usually Num, unless you're using a nonstandard prelude) and interpret it as an (n+k)-binding anywhere else. However, |Let's either disallow (n+k) pattern bindings or always resolve the |ambiguity as an (n+k) pattern. I'd prefer the former, but I never |use (n+k) patterns, anyway. | |Kevin I completely agree with this sentiment. I don't know of any programmer who uses (n+k)-bindings, and at any rate, they are easily replaced by n | n = 0 = e - k I have been bending over backwards to accomodate anyone who thinks we need to retain these things only because that's what we've been doing all along. I seem to recall that the original reason was that such bindings might naturally result from program transformations, but even if this is the case and the above translation is not acceptable for some reason, there is also the alternative of using Lift (n+k) = Lift (e) where data Lift a = Lift a I'm probably preaching to the choir here. Noting that Phil has also said that banning (n+k)-bindings is acceptable, I suggest we do so. Cheers, --Joe
Re: Haskell Report 1.2
|Syntax |~~ |* Left-hand side syntax. PROPOSED DECISION: go with Kevin's suggestion. |It is simple, does not require modification if we abandon n+k patterns, and |nobody has objected to it. Kevin has implemented it, and John Peterson |(our other implementor) agrees. All agree that the present state is awful. |PAUL, JOE: do you concur? (Proposed syntax appears at the end of this |message, for the avoidance of doubt!) I now concur that something must be done. I tried to argue that from a programmer's point of view, the state of the current LHS syntax is not as horridly inconsistent as some have made it out to be, once one agrees to the principle that an aexp (e.g., a pattern with parentheses around the outside) on the left always signals a pattern binding. The more I think about the problem it causes for the parser, though (non-LR(k) for any k), the more I agree that the problem must be fixed. I think that Kevin's suggestion is not quite adequate. A couple of alternatives are proposed at the end of this message. | |* Backquotes. DECIDED: leave as in 1.2beta. | |* Literate style. DECIDED: PHIL to write an appendix. Preferably to include |file-naming conventions too. | |* Syntax of expressions. Is (case fs of {[f] - f} x) allowed? PROPOSED |DECISION (based on my reading of Joe and Paul): no. Meta-rule is that |expressions extend as far to the right as possible. I'M NOT SURE WHAT |NEEDS TO BE ALTERED OR UPDATED HERE! Action JOE/KEVIN. |I *think* all we need is: | fexp - exp^{10} aexp | | aexp I believe the proposed decision is correct. As to how to implement it, the above is what we have now. I think all we need is to change it to the following: fexp- fexp aexp | aexp |Does anything else need to be added to make precedence of case/lambda more |explicit? I don't think so. |* Associativity of (%), (/) | Associativity of :: | JOE TO DECIDE, and tell us I actually hadn't completely spelled this out. I propose that all the operators at this precedence level be made left-associative: infixl 7 /, `div`, `rem`, `mod`, % OK with everybody? | |* Add precedence of @ to the table on page 52. Sounds right to me. ACTION |Glasgow. | |* Should gd - exp^0 be changed back to gd - exp? PROVISIONAL DECISON: no. |We made this choice at Mark Jones' suggestion, to allow us to write |e::T Int rather than e::(T Int). (I can't remember why this guard stuff |is a consequence... No action reqd. | |Prelude |~~~ |* Prelude instances for Text. PROPOSED DECISION: move them to PreludeCore. |This has the merit that waffle about tuple instances only occurs in Core. This means exporting a bunch of supporting functions currently not exported from PreludeText. OK? | |* Various minor bugs in the code. ACTION JOE: you know what they are |because Will has sent them to you. Right. |* Ix class. PROPOSED DECISION: Go with the more restrictive version rather |than permissive version of the constraints in my earlier message (Joe and |Phil both support this). Any objectors? Have I missed some mail here? What more permissive version? Are we talking about defining what index does? I suggested that the proper constraint is range (l,u) !! index (l,u) i == i Is this what you're proposing? |* Add Enum to superclasses of Real, and Ix to superclasses of Integral |(Rittri's suggestion). ACTION JOE to decide. Let's do it. |* Kent's suggestion to change div and rem. JOE TO DECIDE Arrgh! Does anyone (besides Kent) have a strong opinion? |Report presentation |~~~ |* Angle brackets vs curlies for exclusion. DECIDED: we do it. Glasgow |will action. | | | | | |PROPOSED LEFT-HAND-SIDE SYNTAX |~~ | lhs ::= pat{i+1} varop(n,i) pat{i+1} | | lpat{i} varop(l,i) pat{i+1} | | pat{i+1} varop(r,i) pat{i} | | pat | | var apat+ (Aside: There's a typo in the above that's been copied several times in succeeding messages: The third production should be pat{i+1} varop(r,i) rpat{i} End aside) This doesn't cover things like (f .* g) x y = f (g x y) as every previous version of the syntax has. I don't think we should backpedal on this one. A modest increase in the complexity of the proposed syntax allows for this: lhs ::= (var | @(@ ilhs @)@) apat+ | ilhs | pat ilhs ::= pat{i+1} varop(n,i) pat{i+1} | lpat{i} varop(l,i) pat{i+1} | pat{i+1} varop(r,i) rpat{i} I believe this allows for all necessary, but no redundant, parenthesization, except for redundant parenthesization within patterns. ALTERNATE PROPOSAL ~ Make patterns syntactically a sublanguage of expressions, so that lhs is just pat . Make an occurrence of a variable