
At 2001-10-09 11:55, Mark Carroll wrote:
What is the rationale for when Haskell demands a "=" and when it demands a "->"?
What? Example please... -- Ashley Yakeley, Seattle WA

On Tue, 9 Oct 2001, Ashley Yakeley wrote:
At 2001-10-09 11:55, Mark Carroll wrote:
What is the rationale for when Haskell demands a "=" and when it demands a "->"?
What? Example please...
e.g. x :: Integer -> Integer y :: Integer -> Integer z :: Integer -> Integer x 1 = 1 x 2 = 3 y a = case a of 1 -> 1 2 -> 3 z a | a == 1 = 1 | a == 2 = 3 So, for instance, how come function definitions and guards use "=" but lambdas and cases use "->"? -- Mark

Mark Carroll writes:
On Tue, 9 Oct 2001, Ashley Yakeley wrote:
At 2001-10-09 11:55, Mark Carroll wrote:
What is the rationale for when Haskell demands a "=" and when it demands a "->"?
Okay, I can't give you anything formal, but here's my intuitive understanding of things
e.g.
x :: Integer -> Integer
A function "from" and Integer to an Integer. Even more obvious if you have one more parameter: g :: Integer -> Integer -> Integer g takes an Integer and returns a function that takes an Integer and returns an Integer. Equals-assignment would be very non-intuitive here. I guess the same argument goes for lambdas \x -> x*x maps *from* an x *to* its square.
x 1 = 1 x 2 = 3
Function definitions use (=). I'm not sure I see any really compelling reason, except that it's the usual math syntax, and arrows would look weird, in particular with nullary definitions: c -> 0
y a = case a of 1 -> 1 2 -> 3
z a | a == 1 = 1 | a == 2 = 3
It seems there's a predisposition for having exactly one (=) in function definitions. Perhaps one could have had a syntax like z a = | a == 1 -> 1 | a == 2 -> 3 instead, as it'd make it more consisten with the case, but I suppose there's a reason for it being the way it is. The case statement is an expression like any other, while I suspect the guards can only be used in function definitions like your 'z' example. By the way, if you read '=' as "is assigned to", and '|' as "where" and '->' as "gives", things mostly make sense, I think. (Note that there's also the back-arrow, used to "draw from", e.g. in the IO Monad main = do x <- readFile "/etc/passwd" putStr (map crack (lines x)) or list comprehensions primes = [ p | p <- [2..], noDivides p primes] I suppose the difference from (=) assignment is reasonably clear.) Rambling on, -kzm -- If I haven't seen further, it is by standing in the footprints of giants

On 10 Oct 2001, Ketil Malde wrote:
Mark Carroll writes:
On Tue, 9 Oct 2001, Ashley Yakeley wrote:
At 2001-10-09 11:55, Mark Carroll wrote:
What is the rationale for when Haskell demands a "=" and when it demands a "->"?
Okay, I can't give you anything formal, but here's my intuitive understanding of things
e.g.
x :: Integer -> Integer
A function "from" and Integer to an Integer. Even more obvious if you have one more parameter:
g :: Integer -> Integer -> Integer
g takes an Integer and returns a function that takes an Integer and returns an Integer. Equals-assignment would be very non-intuitive here.
As I understand it, the equals sign is used whenever the item on both sides are equal, i.e., one side can be replaced with the other without changing meaning. Of course, in the case of a function definition it's the degenerate equality you get from defining the lhs in terms of the rhs. The -> is used whenever you've got something on the right that `leads to' to something on the left, eg case x of Maybe y ->True Nothing ->False It is not the case that `Maybe y' is the same as True, so = is clearly inappropraite. Likewise for lambdas (\x->x+2 doesn't have x = x+2). It's perhaps less clear because after using functional languages for any length of time you get very used to thinking of function definitions as a restricted kind of rewrite rule, and rewrite rules may not necessarily have any connection to a notion of equality. ___cheers,_dave________________________________________________________ www.cs.bris.ac.uk/~tweed/pi.htm |tweed's law: however many computers email: tweed@cs.bris.ac.uk | you have, half your time is spent work tel: (0117) 954-5250 | waiting for compilations to finish.

On Wed, 10 Oct 2001, D. Tweed wrote:
degenerate equality you get from defining the lhs in terms of the rhs. The -> is used whenever you've got something on the right that `leads to' to ^----left something on the left, eg ^----right
Being bad on these elementary terms makes using foldr, foldl, etc a bit difficult for me :-S ___cheers,_dave________________________________________________________ www.cs.bris.ac.uk/~tweed/pi.htm |tweed's law: however many computers email: tweed@cs.bris.ac.uk | you have, half your time is spent work tel: (0117) 954-5250 | waiting for compilations to finish.

On 10 Oct 2001, Ketil Malde wrote: (snip)
function definitions. Perhaps one could have had a syntax like
z a = | a == 1 -> 1 | a == 2 -> 3
instead, as it'd make it more consisten with the case, but I suppose there's a reason for it being the way it is. The case statement is an (snip)
Ah, yes - it was this 'discrepancy' that was one of the sources of my confusion, as "a == 1" obviously doesn't 'equal' "1". Thanks to you, Ashley and Dave, this is all starting to make some sort of sense, though - thanks to everyone for their thoughts. (-: -- Mark

Mark Carroll wrote (on 09-10-01 20:36 -0400):
On Tue, 9 Oct 2001, Ashley Yakeley wrote:
At 2001-10-09 11:55, Mark Carroll wrote:
What is the rationale for when Haskell demands a "=" and when it demands a "->"?
For me, the difference is that "=" is used when the RHS (right-hand side) is bound to a pattern (or function decl. pattern) LHS in some scope, and "->" when the variables of the pattern on the LHS are free in the expression on the RHS. "<-" behaves like "=". As for "Int -> Int" vs. "\x -> x+1", though the idea of using "->" for binding probably came from the fact that lambda abstraction introduces "->", that's best considered an accident, i.e., you may well assume there is no relationship between these two uses of "->". (In some type systems, they generalize to the same thing, but not in Haskell.) In ML, they use "->" for function types but "=>" for binding constructs. -- Frank Atanassow, Information & Computing Sciences, Utrecht University Padualaan 14, PO Box 80.089, 3508 TB Utrecht, Netherlands Tel +31 (030) 253-3261 Fax +31 (030) 251-379

On Wed, 10 Oct 2001, Mark Carroll wrote:
On 10 Oct 2001, Ketil Malde wrote: (snip)
function definitions. Perhaps one could have had a syntax like
z a = | a == 1 -> 1 | a == 2 -> 3
instead, as it'd make it more consisten with the case, but I suppose there's a reason for it being the way it is. The case statement is an (snip)
Ah, yes - it was this 'discrepancy' that was one of the sources of my confusion, as "a == 1" obviously doesn't 'equal' "1".
I think this comes about from history; in the functional languages like Miranda & Orwell that preceded Haskell an extended version of the function above would have been written z a = 1 if a==1 = 2 if a==2 = 3 otherwise which looks a lot like traditional mathematics and where the equals makes sense. I'm not sure why anymore but Haskell changed the `if clause after the value' to `pattern guard | before =', so I agree it now looks as if it's stating that the pattern guard is equal to the rhs. ___cheers,_dave________________________________________________________ www.cs.bris.ac.uk/~tweed/pi.htm |tweed's law: however many computers email: tweed@cs.bris.ac.uk | you have, half your time is spent work tel: (0117) 954-5250 | waiting for compilations to finish.

On 10-Oct-2001, D. Tweed
On Wed, 10 Oct 2001, Mark Carroll wrote:
On 10 Oct 2001, Ketil Malde wrote: (snip)
function definitions. Perhaps one could have had a syntax like
z a = | a == 1 -> 1 | a == 2 -> 3
instead, as it'd make it more consisten with the case, but I suppose there's a reason for it being the way it is. The case statement is an (snip)
Ah, yes - it was this 'discrepancy' that was one of the sources of my confusion, as "a == 1" obviously doesn't 'equal' "1".
I think this comes about from history; in the functional languages like Miranda & Orwell that preceded Haskell an extended version of the function above would have been written
z a = 1 if a==1 = 2 if a==2 = 3 otherwise
which looks a lot like traditional mathematics and where the equals makes sense. I'm not sure why anymore but Haskell changed the `if clause after the value' to `pattern guard | before =', so I agree it now looks as if it's stating that the pattern guard is equal to the rhs.
I've heard that the company which trademarked "Miranda" also obtained
a design patent on using syntax like that in a programming language.
The enforcibility of such a design patent is IMHO legally dubious,
and the application of design patents to programming languages has
never been tested in court as far as I am aware. But nevertheless
the mere existence of such a design patent was probably a significant
disincentive to using that syntax.
--
Fergus Henderson

On Fri, 12 Oct 2001, Fergus Henderson wrote: [Dave Tweed wrote]
sense. I'm not sure why anymore but Haskell changed the `if clause after the value' to `pattern guard | before =', so I agree it now looks as if it's stating that the pattern guard is equal to the rhs.
I've heard that the company which trademarked "Miranda" also obtained a design patent on using syntax like that in a programming language. The enforcibility of such a design patent is IMHO legally dubious, and the application of design patents to programming languages has never been tested in court as far as I am aware. But nevertheless the mere existence of such a design patent was probably a significant disincentive to using that syntax.
Drifting very quickly offtopic, but this amused me... I think it was probably me that you heard that from (if it was on a post to the main haskell mailing list a couple of years ago.) I was `sure' then that that was the case, having been told independently by two people that was the reason. However, given that no-one from the Haskell comittee corroborated this, and I'd imagine that it isn't something that people would be afraid to admit on the Haskell list (unlike a more fanatical place like /.]), I'm no longer `sure' that the people infrorming me were correct :-) ___cheers,_dave________________________________________________________ www.cs.bris.ac.uk/~tweed/pi.htm |tweed's law: however many computers email: tweed@cs.bris.ac.uk | you have, half your time is spent work tel: (0117) 954-5250 | waiting for compilations to finish.

Being one of the old-timers who was deeply involved in this issue, I can assure you that the decision was not made out of fear that the idea was patented, since in fact this is the first I've heard of that! (All we knew was that the language was trademarked.) If I remember correctly, the main reason was to keep "similar ideas together" -- in this case, pattern matching and guards. With Miranda's syntax, if the body of the function were quite large: foo [x] = <really-huge- multi-line- function-body> if x==1 then the pattern and guard would be greatly separated. This seemed like a bad idea to us. -Paul "D. Tweed" wrote:
On Fri, 12 Oct 2001, Fergus Henderson wrote: [Dave Tweed wrote]
sense. I'm not sure why anymore but Haskell changed the `if clause after the value' to `pattern guard | before =', so I agree it now looks as if it's stating that the pattern guard is equal to the rhs.
I've heard that the company which trademarked "Miranda" also obtained a design patent on using syntax like that in a programming language. The enforcibility of such a design patent is IMHO legally dubious, and the application of design patents to programming languages has never been tested in court as far as I am aware. But nevertheless the mere existence of such a design patent was probably a significant disincentive to using that syntax.
Drifting very quickly offtopic, but this amused me... I think it was probably me that you heard that from (if it was on a post to the main haskell mailing list a couple of years ago.) I was `sure' then that that was the case, having been told independently by two people that was the reason. However, given that no-one from the Haskell comittee corroborated this, and I'd imagine that it isn't something that people would be afraid to admit on the Haskell list (unlike a more fanatical place like /.]), I'm no longer `sure' that the people infrorming me were correct :-)
-- Professor Paul Hudak Chair, Dept of Computer Science Office: (203) 432-1235 Yale University FAX: (203) 432-0593 P.O. Box 208285 email: paul.hudak@yale.edu New Haven, CT 06520-8285 WWW: www.cs.yale.edu/~hudak
participants (7)
-
Ashley Yakeley
-
D. Tweed
-
Fergus Henderson
-
Frank Atanassow
-
Ketil Malde
-
Mark Carroll
-
Paul Hudak