Re: Re[2]: [Haskell-cafe] Why do I have to specify (Monad m) here again?

On 2/18/07, David Tolpin
Why the compiler cannot infer class constraint on m from class definition in instance definition while it can in function type definition?
But it can't! If you give a type to a function, it will assume zero class constraints unless you specify them (just like it will when you give a type to an instance declaration). If you do something like:
Hi Sebastian,
it is not the example I brought. In the example I brought I showed how in function type declaration assertion that an instance of a class is also an instance of the other class is used. Take a look at my example. According to what part of the type system logic type inference in instances is not implemented
That's completely different. The class in that case guarantees that the type has an "Eq" class, so it's okay to use the functions in the "Eq" class. You're using the guarantees supplied by the class. When you write instances, it's the other way around, the class has *requirements* that you must fulfill -- and there are multiple ways of doing it (Haskell won't guess, it will obey what you tell it -- if you don't give any class constraints it won't assume that they are there). The point I'm trying to make is that if you say that something is of a given type, Haskell will assume that you know what you're talking about. I.e. if you give a type which has no class constraints, Haskell will assume that you don't want any class constraints -- if this conflicts with something else, you will get an error. I think maybe this is where you're missing the point. *Leaving out* class constraints says something about the type. In other words, if you leave out a class constraint that does *not* mean that you don't care what class constraints the type variable has, it explicitly means that there are *no* class constraints on it (and using it in a context where a class constraint is required, is thus an error). In this case you *require* that any instances of a class is also an instance of the Monad class. But then you try to instantiate a type which is *not* in the monad class in this class. This is a conflict, and you should get an error. If you want to construct a type which is in the Monad class by constraining the type variable "m" to the Monad class, then that's fine, but you have to tell Haskell that this is what you want to do -- if you say that your type has *no* class constraints, it will take your word for it an report the conflict. Another alternative is that you want to produce the type by using a concrete type called, say, "M" which is in the Monad class, then that's also fine. Haskell won't guess what you meant (it can either be a spelling error, "m" for "M", or that you forgot to add "Monad m =>" in the instance declaration, or anynumber of other errors) and change it for you. Whenever you write something out, Haskell will take your word for it, if it fails, it's your fault, and Haskell will tell you what the problem is. -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862

That's completely different. The class in that case guarantees that the type has an "Eq" class, so it's okay to use the functions in the "Eq" class. You're using the guarantees supplied by the class. When you write instances, it's the other way around, the class has *requirements* that you must fulfill -- and there are multiple ways of doing it (Haskell won't guess, it will obey what you tell it -- if you don't give any class constraints it won't assume that they are there).
Hi Sebastian, could you please point me to a reference (paper/note/something else) that explains that class constraint in a class definition is a guarantee with regard to a type declaration but a requirement with regard to an instance declaration? David Tolpin

On 2/18/07, David Tolpin
That's completely different. The class in that case guarantees that the type has an "Eq" class, so it's okay to use the functions in the "Eq" class. You're using the guarantees supplied by the class. When you write instances, it's the other way around, the class has *requirements* that you must fulfill -- and there are multiple ways of doing it (Haskell won't guess, it will obey what you tell it -- if you don't give any class constraints it won't assume that they are there).
Hi Sebastian,
could you please point me to a reference (paper/note/something else) that explains that class constraint in a class definition is a guarantee with regard to a type declaration but a requirement with regard to an instance declaration?
Well, I guess the H98 report would be a good start. But there are multiple tutorials on type classes that will cover this, most of which are available from haskell.org The key point is that Haskell won't guess, and in particular it won't contradict what you tell it. I think that's the major flaw in your reasoning, you expect Haskell to take an explicit type that you, the programmer, supplies, and change it into something else. That's obviously not a very good idea -- when there's a conflict, it should give an error. In the original example you are explicitly telling Haskell that "m" is *not* in the Monad (or any other) class. Why would you want Haskell to ignore what you are telling it and go behind your back? Another way to view this specific issue is that it's two-sided -- if you on the one hand have a guarantee that something holds, then logically on the other side there must be a requirement to fulfill that guarantee. Now, if you have a guarantee (e.g. if a variable is in the Ord class, you are allowed to use (==) due to Eq being a super class), you can just make use of that guarantee without any further fuss. But if you have a *requirement* then it's a completely different story since there are any number of ways to fulfill that requirement (Haskell is, sadly, incapable of reading the programmer's mind). Take the example I gave earlier; maybe the "m" in the original example was supposed to be "M" (a type in the Monad class), or maybe it was supposed to be constrained to "Monad", or any other class which has "Monad" in its class hierarchy. Haskell has *no* way of knowing how you intend to fulfill the requirement that any instance in your class is a Monad (which is required to fulfill the guarantee that the functions in Monad can be used on any instance of your class), and it won't guess. -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862

On Mon, 19 Feb 2007 00:30:47 +0400, Sebastian Sylvan
Well, I guess the H98 report would be a good start. But there are multiple tutorials on type classes that will cover this, most of which are available from haskell.org
Sebastian, I did read H98 and would like an exact reference.
The key point is that Haskell won't guess, and in particular it won't contradict what you tell it. I think that's the major flaw in your reasoning, you expect Haskell to take an explicit type that you, the programmer, supplies, and change it into something else.
Why is this rule applied differently to type declarations and to instances?
In the original example you are explicitly telling Haskell that "m" is *not* in the Monad (or any other) class.
I am not telling that. I am telling that m is an instance of a class all instances of which are in the Monad class. How is this different from specifying class constraint in type declarations? David

On 2/18/07, David Tolpin
On Mon, 19 Feb 2007 00:30:47 +0400, Sebastian Sylvan
wrote: Well, I guess the H98 report would be a good start. But there are multiple tutorials on type classes that will cover this, most of which are available from haskell.org
Sebastian,
I did read H98 and would like an exact reference.
I'm sorry, I don't have the time to look it up for you. There are tons of resource on this issue. I'm trying to explain it to you, if you don't believe me then you'll just have to make do without my help.
The key point is that Haskell won't guess, and in particular it won't contradict what you tell it. I think that's the major flaw in your reasoning, you expect Haskell to take an explicit type that you, the programmer, supplies, and change it into something else.
Why is this rule applied differently to type declarations and to instances?
It isn't. What makes you think it is? If you supply a type it will trust you with that type. It won't change it into something else. That's always true.
In the original example you are explicitly telling Haskell that "m" is *not* in the Monad (or any other) class.
I am not telling that. I am telling that m is an instance of a class all instances of which are in the Monad class. How is this different from specifying class constraint in type declarations?
No, you're saying "I want to instantiate this type into a class which *requires* that all instances are in the Monad class". The thing is that there are multiple ways of meeting this requriement, and Haskell has no way of guessing which way you intended to do it. A type variable "m" without any class constraints means exactly that, "here's a type variable, it has no class constraints". The *absence* of class constraints is significant -- it doesn't mean "I don't care", it means "I care, and there are no constraints". And a type variable with no constraints in a context which requires constraints is a type error. How is Haskell supposed to know if you want to inject a "Monad" class constraint or not, in your original example? You could just as well add, say, "MonadIO" or "MonadPlus" or any other classes which have Monad in their class hierarchy, any one of which would satisfy the requirement that "m" needs to be in the "Monad" class. Also, the misstake might be due to a spelling error, or any number of other errors. I don't understand why you would want Haskell to ignore the explicit type you are giving (in the instance declaration), which has no constraints, and do something else instead. -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862

At 12:42 AM +0400 2/19/07, David Tolpin wrote:
On Mon, 19 Feb 2007 00:30:47 +0400, Sebastian Sylvan
wrote: Well, I guess the H98 report would be a good start. But there are multiple tutorials on type classes that will cover this, most of which are available from haskell.org
Sebastian,
I did read H98 and would like an exact reference.
See section 4.3.2, the third bullet item in the bulleted list. (Note that the last sentence of that bullet item says that context inference--though often possible--is deliberately eschewed.)
The key point is that Haskell won't guess, and in particular it won't contradict what you tell it. I think that's the major flaw in your reasoning, you expect Haskell to take an explicit type that you, the programmer, supplies, and change it into something else.
Why is this rule applied differently to type declarations and to instances?
In the original example you are explicitly telling Haskell that "m" is *not* in the Monad (or any other) class.
I am not telling that. I am telling that m is an instance of a class all instances of which are in the Monad class. How is this different from specifying class constraint in type declarations?
David

David Tolpin wrote:
could you please point me to a reference (paper/note/something else) that explains that class constraint in a class definition is a guarantee with regard to a type declaration but a requirement with regard to an instance declaration?
Sebastian Sylvan wrote:
Well, I guess the H98 report would be a good start.
I'm not sure that is a good place to start. True, it is likely possible to deduce both of those facts from the Report. But the Report is a language spec. It assumes that you already know about the type system, and it is difficult to read if you don't.
...there are multiple tutorials on type classes that will cover this, most of which are available from haskell.org
That sounds like a much better idea. Any particular suggestions? Thanks, Yitz
participants (4)
-
David Tolpin
-
Dean Herington
-
Sebastian Sylvan
-
Yitzchak Gale