
Why can polymorphic data constructors not be instantiated as a class? (not sure if I used the right terminology there) For example, a = [1,True]::[Show] b = "foo":a c = map show b This would obviate the need for wrapper types

John Smith
Why can polymorphic data constructors not be instantiated as a class? (not sure if I used the right terminology there)
For example,
a = [1,True]::[Show] b = "foo":a c = map show b
This would obviate the need for wrapper types
Your type signature doesn't make sense. You are confusing type classes with types. Show is a type class. As far as I see, you will need a wrapper type: data Object = forall a. Show a => Object { unObject :: a } a = [Object 1, Object True] b = Object "foo" : a c = map (show . unObject) b I have not tested this code, though. At least I can get the following list to type-check (using RankNTypes and ImpredicativeTypes extensions): [1,2,3] :: [forall a. Num a => a] but I can't use it in any way. And somehow I also can't mix data types here. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/

On 23/08/2010 18:32, Ertugrul Soeylemez wrote:
John Smith
wrote: Why can polymorphic data constructors not be instantiated as a class? (not sure if I used the right terminology there)
For example,
a = [1,True]::[Show] b = "foo":a c = map show b
This would obviate the need for wrapper types
Your type signature doesn't make sense. You are confusing type classes with types. Show is a type class.
My question was why doesn't the type system allow classes to be used in this way. It's the equivalent of a base class or interface in OO.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 8/23/10 12:12 , John Smith wrote:
On 23/08/2010 18:32, Ertugrul Soeylemez wrote:
John Smith
wrote: Why can polymorphic data constructors not be instantiated as a class? (not sure if I used the right terminology there)
For example,
a = [1,True]::[Show] b = "foo":a c = map show b
This would obviate the need for wrapper types
Your type signature doesn't make sense. You are confusing type classes with types. Show is a type class.
My question was why doesn't the type system allow classes to be used in this way. It's the equivalent of a base class or interface in OO.
Typeclasses are not classes, and Haskell values are not objects. In OO languages, objects carry around dictionaries with full details of what they can do. Haskell values, on the other hand, don't actually carry around anything; what they can do is specified by the type. If the type is (Show a => [a]), that means the *only* thing you can do with an (a) is to call (show) on it. (1) Since this is almost certainly not what you intend, Haskell insists you acknowledge that by specifying the type as ([forall a. Show a => a]), making it explicit that the scope of (a) is limited to inside the brackets --- meaning that, since anything wanting to use it has to go through the brackets, *all* it knows is that it can invoke (show) on it. (2) Again, values are not objects --- there is no method dictionary hidden inside of them. Typeclass dictionaries are carried *outside* of values, as hidden arguments to functions that are declared with types that are typeclass members. Which is why you can't say (a = [1,True] :: [forall a. Show a => a]): there's nowhere to put the dictionary in the value ([1,True]). This is why a wrapper is required; the wrapper provides a place for the hidden argument. Summary: If you want an OO language, use an OO language. Haskell isn't one. There are some outdated examples of OO extensions for Haskell that I don't think are maintained any more, notably "OOHaskell". They're not maintained due to lack of interest. If you want such a thing, you'll have to modernize it yourself. - -- brandon s. allbery [linux,solaris,freebsd,perl] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkxyr6EACgkQIn7hlCsL25XW/QCZAcpQFDxw/ukQlOpPn5zA18tE vH0AoIh944GcFo1ASFoLxvIHldY9v5DR =F+gL -----END PGP SIGNATURE-----

On 08/23/10 13:28, Brandon S Allbery KF8NH wrote:
Summary: If you want an OO language, use an OO language. Haskell isn't one.
There are some outdated examples of OO extensions for Haskell that I don't think are maintained any more, notably "OOHaskell". They're not maintained due to lack of interest. If you want such a thing, you'll have to modernize it yourself.
I wouldn't take that advice too literally-- When I was first learning Haskell I was interested in O'Haskell (or whatever it was called), but now that I've used Haskell for longer, I get along quite happily with its type-system and way of thinking about things, and rarely want OO. -Isaac

On 23/08/2010 20:28, Brandon S Allbery KF8NH wrote:
On 8/23/10 12:12 , John Smith wrote:
On 23/08/2010 18:32, Ertugrul Soeylemez wrote:
John Smith
wrote: Why can polymorphic data constructors not be instantiated as a class? (not sure if I used the right terminology there)
For example,
a = [1,True]::[Show] b = "foo":a c = map show b
This would obviate the need for wrapper types
Your type signature doesn't make sense. You are confusing type classes with types. Show is a type class.
My question was why doesn't the type system allow classes to be used in this way. It's the equivalent of a base class or interface in OO.
Typeclasses are not classes, and Haskell values are not objects. In OO languages, objects carry around dictionaries with full details of what they can do. Haskell values, on the other hand, don't actually carry around anything; what they can do is specified by the type. If the type is (Show a => [a]), that means the *only* thing you can do with an (a) is to call (show) on it.
(1) Since this is almost certainly not what you intend,
Wouldn't this be a useful feature? For example, [Show] could contain a list of values for serialising to strings, and ditto for any other typeclass. When you say "Since this is almost certainly not what you intend", is there something else which could be intended by such code?
Haskell insists you acknowledge that by specifying the type as ([forall a. Show a => a]), making it explicit that the scope of (a) is limited to inside the brackets --- meaning that, since anything wanting to use it has to go through the brackets, *all* it knows is that it can invoke (show) on it.
(2) Again, values are not objects --- there is no method dictionary hidden inside of them. Typeclass dictionaries are carried *outside* of values, as hidden arguments to functions that are declared with types that are typeclass members. Which is why you can't say (a = [1,True] :: [forall a. Show a => a]): there's nowhere to put the dictionary in the value ([1,True]). This is why a wrapper is required; the wrapper provides a place for the hidden argument.
Summary: If you want an OO language, use an OO language. Haskell isn't one.
There are some outdated examples of OO extensions for Haskell that I don't think are maintained any more, notably "OOHaskell". They're not maintained due to lack of interest. If you want such a thing, you'll have to modernize it yourself.
I don't want OO, just for typeclasses to be usable as types in polymorphism, seeing as both are equally relevant as a definition of constraints. (There's probably a better way to word that.)

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 8/23/10 15:17 , John Smith wrote:
On 23/08/2010 20:28, Brandon S Allbery KF8NH wrote:
Typeclasses are not classes, and Haskell values are not objects. In OO languages, objects carry around dictionaries with full details of what they can do. Haskell values, on the other hand, don't actually carry around anything; what they can do is specified by the type. If the type is (Show a => [a]), that means the *only* thing you can do with an (a) is to call (show) on it.
(1) Since this is almost certainly not what you intend,
Wouldn't this be a useful feature? For example, [Show] could contain a list
It can be useful at times, which is why you can write it out the long way. But consider something like ([forall n. Num n => n]); the dictionary contains the basic math operations (see the definition of Num; you also get Eq and Show, but nothing else. Not even Ord, since complex numbers don't have a well defined ordering) and they are specialized for the exact type of the object, but you don't know what that type is so you can't really apply it to anything else. (Not even to another member of the list, since it doesn't have the type of that object, it has the type (forall n. Num n => n).) On the other hand, carrying around type and/or method information for every value is fairly expensive, and lazy languages are already slow because of the extra work (basically, "lazy" means every expression is actually a closure which produces the value of that expression when invoked). This is what "unboxing" is about, which you'll see mentioned in almost every discussion of optimization or performance in Haskell). Including a method dictionary means *another* level of indirection for every expression and every evaluation step, and then if you make the dictionary lazy as well then it's still another level of indirection per evaluation.
of values for serialising to strings, and ditto for any other typeclass. When you say "Since this is almost certainly not what you intend", is there something else which could be intended by such code?
Most people, on seeing that, would expect it to mean "I get to use all the operations legal on the type of the value I gave it, as long as that type is a member of Show". But it actually means "I can only use operations legal on values whose type is a member of Show".
I don't want OO, just for typeclasses to be usable as types in polymorphism, seeing as both are equally relevant as a definition of constraints. (There's probably a better way to word that.)
You may have phrased that wrongly indeed; I would recognize that as subtyping, which is a form of dependent types. Which is a rather more complex ball of type spaghetti. - -- brandon s. allbery [linux,solaris,freebsd,perl] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkxyzUYACgkQIn7hlCsL25VZVACgvX0aLQwioqkOSByVdfA9jAo5 MPIAoLR55POz5SjHki7Pcui7nmn1fS2u =8aCZ -----END PGP SIGNATURE-----
participants (4)
-
Brandon S Allbery KF8NH
-
Ertugrul Soeylemez
-
Isaac Dupree
-
John Smith