
Hi, I try to undestand why this code dosen't work f :: (Num a)=>Integer->a f i = i Integer is an instance of Num, so why does this code produce error: "Couldn't match expected type 'a' againsta inferred type 'Integer' ..."

2008/1/21 Alexander Seliverstov
Hi, I try to undestand why this code dosen't work
f :: (Num a)=>Integer->a
f i = i
Integer is an instance of Num, so why does this code produce error: "Couldn't match expected type 'a' againsta inferred type 'Integer' ..."
But the type of this function says that it can return *any* instance of Num -- that is, the caller gets to choose which particular instance of Num they want. This function can only ever return an Integer. There is actually a function of this type, however; it's called fromIntegral. It works because it is a member of the Num type class. -Brent

How does caller choose which particular instance of Num they want?
In object-oriented language If function return type is an interface it means
that it can return any implementation of this interface, but caller can't
choose which particular inplementation they want.
What the difference between haskell class and interface in object-oriented
languge such Java or C#?
2008/1/21, Brent Yorgey
2008/1/21 Alexander Seliverstov
: Hi, I try to undestand why this code dosen't work
f :: (Num a)=>Integer->a
f i = i
Integer is an instance of Num, so why does this code produce error: "Couldn't match expected type 'a' againsta inferred type 'Integer' ..."
But the type of this function says that it can return *any* instance of Num -- that is, the caller gets to choose which particular instance of Num they want. This function can only ever return an Integer.
There is actually a function of this type, however; it's called fromIntegral. It works because it is a member of the Num type class.
-Brent

"Alexander Seliverstov"
How does caller choose which particular instance of Num they want?
They specify the type... or just pass the result to something that specifies the type. Try it in ghci: Prelude> let f:: Integral i => Integer -> i; f = fromIntegral Prelude> let g :: Int -> Int; g = id Prelude> :t g (f 5) g (f 5) :: Int Prelude> let h :: Integer -> Integer; h = id Prelude> :t h (f 5) h (f 5) :: Integer Prelude>
What the difference between haskell class and interface in object-oriented languge such Java or C#?
Really they are completely different animals that look a lot alike because they serve similar purposes -- convergent evolution! -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

So, the function type "(Num a)=>Integer->a" means that return value of this
function can be cast to any particular instance of class Num.
Ok. I have a my own class "class A a" and want to write function like this
"f:: (A a)=>Integer->a". Can I do it?
2008/1/21, Jon Fairbairn
"Alexander Seliverstov"
writes: How does caller choose which particular instance of Num they want?
They specify the type... or just pass the result to something that specifies the type. Try it in ghci:
Prelude> let f:: Integral i => Integer -> i; f = fromIntegral Prelude> let g :: Int -> Int; g = id Prelude> :t g (f 5) g (f 5) :: Int Prelude> let h :: Integer -> Integer; h = id Prelude> :t h (f 5) h (f 5) :: Integer Prelude>
What the difference between haskell class and interface in object-oriented languge such Java or C#?
Really they are completely different animals that look a lot alike because they serve similar purposes -- convergent evolution!
-- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- С уважением, Селиверстов Александр

2008/1/21 Alexander Seliverstov
So, the function type "(Num a)=>Integer->a" means that return value of this function can be cast to any particular instance of class Num.
Ok. I have a my own class "class A a" and want to write function like this "f:: (A a)=>Integer->a". Can I do it?
Only if you make the function f a member of class A. Then it is the responsibility of each particular type which is an instance of A to define a way of converting an Integer into a value of that type. For example: class A a where f :: Integer -> a ... other functions... instance A Integer where f = id instance A String where f = show and so on. -Brent

"Alexander Seliverstov"
So, the function type "(Num a)=>Integer->a" means that return value of this function can be cast to any particular instance of class Num.
For some meanings of the word "cast" yes. I'd rather say "f:: Num a=> Integer -> a" means that for any type a that is an instance of Num, given an integer f will return a member of that type.
Ok. I have a my own class "class A a" and want to write function like this "f:: (A a)=>Integer->a". Can I do it?
You need to be a bit more specific about what f is supposed to do without that, I can answer unequivocally yes, and give you f:: (A a) => Integer -> a f n = undefined :-P But in general you are going to want something a bit more useful, which means that you have to have a path from Integer to a -- what the path can be is depends on what "methods" you give class A. For example: class A a where first_a :: a second_a :: a f :: A t => Integer -> t f n | odd n = first_a | otherwise = second_a -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

Thanks. I get it.
2008/1/21, Jon Fairbairn
"Alexander Seliverstov"
writes: So, the function type "(Num a)=>Integer->a" means that return value of this function can be cast to any particular instance of class Num.
For some meanings of the word "cast" yes. I'd rather say "f:: Num a=> Integer -> a" means that for any type a that is an instance of Num, given an integer f will return a member of that type.
Ok. I have a my own class "class A a" and want to write function like this "f:: (A a)=>Integer->a". Can I do it?
You need to be a bit more specific about what f is supposed to do without that, I can answer unequivocally yes, and give you
f:: (A a) => Integer -> a f n = undefined
:-P
But in general you are going to want something a bit more useful, which means that you have to have a path from Integer to a -- what the path can be is depends on what "methods" you give class A. For example:
class A a where first_a :: a second_a :: a
f :: A t => Integer -> t f n | odd n = first_a | otherwise = second_a
-- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- С уважением, Селиверстов Александр

Hello Jon, Monday, January 21, 2008, 9:28:09 PM, you wrote:
Ok. I have a my own class "class A a" and want to write function like this "f:: (A a)=>Integer->a". Can I do it?
But in general you are going to want something a bit more useful, which means that you have to have a path from Integer to a
i.e. you should have other functions that produce A from Integer and at the last end this means that class A should provide some way to do it -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Bulat Ziganshin
Hello Jon,
Monday, January 21, 2008, 9:28:09 PM, you wrote:
Ok. I have a my own class "class A a" and want to write function like this "f:: (A a)=>Integer->a". Can I do it?
But in general you are going to want something a bit more useful, which means that you have to have a path from Integer to a
i.e. you should have other functions that produce A from Integer and at the last end this means that class A should provide some way to do it
I'm not sure we're using the same terminology. In the example I gave, the class A doesn't provide anything from Integer to a, unless defining an overloaded function outside the class definition counts as the class providing something. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk

Hello Jon, Tuesday, January 22, 2008, 1:04:48 PM, you wrote:
i.e. you should have other functions that produce A from Integer and at the last end this means that class A should provide some way to do it
I'm not sure we're using the same terminology. In the example I gave, the class A doesn't provide anything from Integer to a, unless defining an overloaded function outside the class definition counts as the class providing something.
you are perfectly right. but don't forget that this is not theoretical discussion but *newbie* question so i hope that my answer is just what he try to realize. anyway, he got them both -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Hello Alexander, Monday, January 21, 2008, 8:28:33 PM, you wrote:
So, the function type "(Num a)=>Integer->a" means that return value of this function can be cast to any particular instance of class Num.
no! this means that the function really can return value of any type - the calller (implicitly, via dictionary) says which type should be returned -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Hello Alexander, Monday, January 21, 2008, 7:36:18 PM, you wrote:
How does caller choose which particular instance of Num they want?
In object-oriented language If function return type is an interface it means that it can return any implementation of this interface, but caller can't choose which particular inplementation they want.
but type class isn't an interface! it's just like interface in one concrete area - it includes method specifications, but not includes data fields the type that should ìó returned by function is passed by means of so-called dictionary and which type should be returned is defined by type inference process. for example main = print (length [] + f 1) here f should return Int because length return Int and you can't add values of different types (without explicit type conversion). you should also read something about two-way type inference but i don't know any good source please note that in modern OOP languages (latest C# versions, C++ 0x) support for *one-way* type inference was only added, i.e. they only can deduce type of expression from types of operands, while Haskell deduces types in both directions -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

How does caller choose which particular instance of Num they want?
By passing the type they want. That's what the "Num a =>" thingy does.
In object-oriented language If function return type is an interface it means that it can return any implementation of this interface, but caller can't choose which particular inplementation they want.
The full type of "f" you've given is: forall a . (Num a) => Integer -> a where the "forall a ." is normally not written. What you describe (a function that returns something where the type can be chosen by the function itself) would have type: Integer -> (exists a . (Num a) => a) I.e. the "a" is not passed as a (type) argument, but instead it's returned by the function.
What the difference between haskell class and interface in object-oriented languge such Java or C#?
From a low-level point of view, the difference is that the vtable is manipulated separately from the objects. The "Num a" basically stands for the type of the vtable (which is called "dictionary" in Haskell).
To bundle an object with its vtable as is traditionally done in OO languages, you need to create an existential package, e.g. something of type (exists a . (Num a) => a). Stefan

Hey, I knew about the forall (I use that to represent OO style collections, very handy), but not about the exists. Thanks. But GHC 6.8.2 (with -fglasgow-exts) does not seem to accept this "exists" keyword? Does a book or document already exist (except the website) that tells more about not standarized yet very cool Haskell thingies that make writing real world applications possible? I would LOVE such a book. Cheers, Peter On Mon, 2008-01-21 at 16:10 -0500, Stefan Monnier wrote:
How does caller choose which particular instance of Num they want?
By passing the type they want. That's what the "Num a =>" thingy does.
In object-oriented language If function return type is an interface it means that it can return any implementation of this interface, but caller can't choose which particular inplementation they want.
The full type of "f" you've given is:
forall a . (Num a) => Integer -> a
where the "forall a ." is normally not written. What you describe (a function that returns something where the type can be chosen by the function itself) would have type:
Integer -> (exists a . (Num a) => a)
I.e. the "a" is not passed as a (type) argument, but instead it's returned by the function.
What the difference between haskell class and interface in object-oriented languge such Java or C#?
From a low-level point of view, the difference is that the vtable is manipulated separately from the objects. The "Num a" basically stands for the type of the vtable (which is called "dictionary" in Haskell).
To bundle an object with its vtable as is traditionally done in OO languages, you need to create an existential package, e.g. something of type (exists a . (Num a) => a).
Stefan
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Mon, 2008-01-21 at 22:36 +0100, Peter Verswyvelen wrote:
Hey, I knew about the forall (I use that to represent OO style collections, very handy), but not about the exists. Thanks. But GHC 6.8.2 (with -fglasgow-exts) does not seem to accept this "exists" keyword?
That's because it isn't GHC syntax, Stefan was just using for demonstration purposes. (However, I think HBC does accept free existentials.) GHC does support local existentials (with two different syntaxes) and that's what you are probably using to make your "OO style collections". When you write: data Foo = forall a.Foo (Num a => a) this is an -existential-. The type of (the data constructor) Foo is: Foo :: forall a.(Num a => a) -> Foo The rules of logic give: Foo :: (exists a.Num a => a) -> Foo note the change in scoping and compare this to local universal quantification: data Foo = Foo (forall a.Num a => a) Foo :: (forall a.Num a => a) -> Foo

Am Montag, 21. Januar 2008 21:55 schrieb Derek Elkins:
On Mon, 2008-01-21 at 22:36 +0100, Peter Verswyvelen wrote:
Hey, I knew about the forall (I use that to represent OO style collections, very handy), but not about the exists. Thanks. But GHC 6.8.2 (with -fglasgow-exts) does not seem to accept this "exists" keyword?
That's because it isn't GHC syntax, Stefan was just using for demonstration purposes. (However, I think HBC does accept free existentials.) GHC does support local existentials (with two different syntaxes) and that's what you are probably using to make your "OO style collections". When you write: data Foo = forall a.Foo (Num a => a) this is an -existential-. The type of (the data constructor) Foo is: Foo :: forall a.(Num a => a) -> Foo
I think you have a typo here. The type of the data constructor should be this: forall a. Num a => (a -> Foo)
The rules of logic give: Foo :: (exists a.Num a => a) -> Foo note the change in scoping and compare this to local universal quantification: data Foo = Foo (forall a.Num a => a) Foo :: (forall a.Num a => a) -> Foo
Best wishes, Wolfgang

Hello Peter, Tuesday, January 22, 2008, 12:36:49 AM, you wrote:
Hey, I knew about the forall (I use that to represent OO style collections, very handy), but not about the exists. Thanks. But GHC 6.8.2 (with -fglasgow-exts) does not seem to accept this "exists" keyword?
Does a book or document already exist (except the website) that tells more about not standarized yet very cool Haskell thingies that make writing real world applications possible? I would LOVE such a book.
are you read GHC docs? its chapter 7 is all about language extensions and also contains further references -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Hello Alexander, Monday, January 21, 2008, 6:37:38 PM, you wrote:
Hi, I try to undestand why this code dosen't work f :: (Num a)=>Integer->a f i = i
as for every beginner which tries to grok type classes, i recommend you to read http://haskell.org/haskellwiki/OOP_vs_type_classes and especially papers mentioned there in References section also, i recommend you to subscribe to ru_declarative and ru_lambda LiveJournal communities and read them back - several month ago i've placed there simple explanation of differences between C++ templates, OOP classes and Haskell type classes -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
participants (8)
-
Alexander Seliverstov
-
Brent Yorgey
-
Bulat Ziganshin
-
Derek Elkins
-
Jon Fairbairn
-
Peter Verswyvelen
-
Stefan Monnier
-
Wolfgang Jeltsch