special polymorphic default of typeclass depending on other typeclasses?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

special polymorphic default of typeclass depending on other typeclasses?

Silent Leaf
hi,

say i have the following typeclass:

class Foo a where
  bar :: a  -> String

looks a lot like the Read typeclass, right? (at least i think it should?)
well say it's a different meaning (in other terms i can't or do not want to use Read, but i'd like to implement a default version of bar for those instances that also implement Read. is there a way to do so?

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: special polymorphic default of typeclass depending on other typeclasses?

Jean Lopes
It appear more like Show, you can add a  constraint to the generic instance

instance Show a => Foo a where
    bar x = show x




Em 29 de jun de 2017 2:16 PM, "Silent Leaf" <[hidden email]> escreveu:
hi,

say i have the following typeclass:

class Foo a where
  bar :: a  -> String

looks a lot like the Read typeclass, right? (at least i think it should?)
well say it's a different meaning (in other terms i can't or do not want to use Read, but i'd like to implement a default version of bar for those instances that also implement Read. is there a way to do so?

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners



_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: special polymorphic default of typeclass depending on other typeclasses?

Sylvain Henry-2

Constraints aren't considered when instance selection is performed. I.e. you can't have both:
instance Foo a where ...
instance Show a => Foo a where ....

But you can use default method signatures: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#default-method-signatures


On 29/06/2017 19:27, Jean Lopes wrote:
It appear more like Show, you can add a  constraint to the generic instance

instance Show a => Foo a where
    bar x = show x




Em 29 de jun de 2017 2:16 PM, "Silent Leaf" <[hidden email]> escreveu:
hi,

say i have the following typeclass:

class Foo a where
  bar :: a  -> String

looks a lot like the Read typeclass, right? (at least i think it should?)
well say it's a different meaning (in other terms i can't or do not want to use Read, but i'd like to implement a default version of bar for those instances that also implement Read. is there a way to do so?

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners




_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: special polymorphic default of typeclass depending on other typeclasses?

David McBride
In reply to this post by Silent Leaf
This is a common mistake that people who try to use type classes run
into.  I remember banging my head against it pretty hard when I first
started out.

There's this temptation that  you should be able to write the following:

class Foo a where
  bar :: a  -> String

instance Read a => Foo a where
  bar a = read a

instance Foo () where
  bar _ = "bar"

But the problem with that is that now () applies to two conflicting
classes.  It is both a Read and a Foo. So when you go bar (), which
instance should fire?  The Foo instance or the Read () => Foo
instance?

There are a multitude of ways you could try to resolve this.  Let's
say obviously the Read constrainted instance is more specific, we
should use that.  But then what if the user of your library happens to
have a instance Ord a => Foo a in his library, now which one of those
is more specific?  Read or Ord?

Because of all these ambiguities during type checking ghc doesn't even
look at the constraint.  It would see instance Foo a, and instance Foo
(), and then say oh! those are overlapping instances because () could
apply to either class before you consider what constraints apply.

There's actually several very in depth answers on stackoverflow for
this questions like this, such as this one:
https://stackoverflow.com/a/3216937/1500583  It might give you some
ideas on what to do about this.

On Thu, Jun 29, 2017 at 1:15 PM, Silent Leaf <[hidden email]> wrote:

> hi,
>
> say i have the following typeclass:
>
> class Foo a where
>   bar :: a  -> String
>
> looks a lot like the Read typeclass, right? (at least i think it should?)
> well say it's a different meaning (in other terms i can't or do not want to
> use Read, but i'd like to implement a default version of bar for those
> instances that also implement Read. is there a way to do so?
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: special polymorphic default of typeclass depending on other typeclasses?

Silent Leaf
you're right my example is more like Show, it's because i change two times the order of input and output, and did not check at the end if it was what i wanted...

Actually i did not mean constraints on instances, especially thereafter ad-hoc polymorphic instances.
I rather meant what i said, as in default implementation (as in, right inside the body of the class).
like that:

class Foo a where
  bar :: a -> String
  bar :: Show a => a -> String
  bar = show -- default implementation: in other terms, if you define an instance without defining this method

the idea would be then that if you have Foo (), you can either implement a special version, or leave it to show. mind you i'm not even sure we can define an instance without any specific implementation of method?

--that would be allowed:
instance Show => Foo () where
  -- nothing, if it's even legal by default

-- and of course that would be allowed to if someone wanted a special function bar :: Foo () => () -> String
instance Foo () where
  bar = ....

obviously, i do not mean *both* instances of Foo (), just, one or the other. it would merely be a way to implement ad-hoc polymorphism onto *default implementations of methods*, that is, those inside the body of the class.



2017-06-29 19:45 GMT+02:00 David McBride <[hidden email]>:
This is a common mistake that people who try to use type classes run
into.  I remember banging my head against it pretty hard when I first
started out.

There's this temptation that  you should be able to write the following:

class Foo a where
  bar :: a  -> String

instance Read a => Foo a where
  bar a = read a

instance Foo () where
  bar _ = "bar"

But the problem with that is that now () applies to two conflicting
classes.  It is both a Read and a Foo. So when you go bar (), which
instance should fire?  The Foo instance or the Read () => Foo
instance?

There are a multitude of ways you could try to resolve this.  Let's
say obviously the Read constrainted instance is more specific, we
should use that.  But then what if the user of your library happens to
have a instance Ord a => Foo a in his library, now which one of those
is more specific?  Read or Ord?

Because of all these ambiguities during type checking ghc doesn't even
look at the constraint.  It would see instance Foo a, and instance Foo
(), and then say oh! those are overlapping instances because () could
apply to either class before you consider what constraints apply.

There's actually several very in depth answers on stackoverflow for
this questions like this, such as this one:
https://stackoverflow.com/a/3216937/1500583  It might give you some
ideas on what to do about this.

On Thu, Jun 29, 2017 at 1:15 PM, Silent Leaf <[hidden email]> wrote:
> hi,
>
> say i have the following typeclass:
>
> class Foo a where
>   bar :: a  -> String
>
> looks a lot like the Read typeclass, right? (at least i think it should?)
> well say it's a different meaning (in other terms i can't or do not want to
> use Read, but i'd like to implement a default version of bar for those
> instances that also implement Read. is there a way to do so?
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: special polymorphic default of typeclass depending on other typeclasses?

Silent Leaf
typos in my previous message (including in the code), don't pay attention, any error is an error :P

2017-06-29 20:08 GMT+02:00 Silent Leaf <[hidden email]>:
you're right my example is more like Show, it's because i change two times the order of input and output, and did not check at the end if it was what i wanted...

Actually i did not mean constraints on instances, especially thereafter ad-hoc polymorphic instances.
I rather meant what i said, as in default implementation (as in, right inside the body of the class).
like that:

class Foo a where
  bar :: a -> String
  bar :: Show a => a -> String
  bar = show -- default implementation: in other terms, if you define an instance without defining this method

the idea would be then that if you have Foo (), you can either implement a special version, or leave it to show. mind you i'm not even sure we can define an instance without any specific implementation of method?

--that would be allowed:
instance Show => Foo () where
  -- nothing, if it's even legal by default

-- and of course that would be allowed to if someone wanted a special function bar :: Foo () => () -> String
instance Foo () where
  bar = ....

obviously, i do not mean *both* instances of Foo (), just, one or the other. it would merely be a way to implement ad-hoc polymorphism onto *default implementations of methods*, that is, those inside the body of the class.



2017-06-29 19:45 GMT+02:00 David McBride <[hidden email]>:
This is a common mistake that people who try to use type classes run
into.  I remember banging my head against it pretty hard when I first
started out.

There's this temptation that  you should be able to write the following:

class Foo a where
  bar :: a  -> String

instance Read a => Foo a where
  bar a = read a

instance Foo () where
  bar _ = "bar"

But the problem with that is that now () applies to two conflicting
classes.  It is both a Read and a Foo. So when you go bar (), which
instance should fire?  The Foo instance or the Read () => Foo
instance?

There are a multitude of ways you could try to resolve this.  Let's
say obviously the Read constrainted instance is more specific, we
should use that.  But then what if the user of your library happens to
have a instance Ord a => Foo a in his library, now which one of those
is more specific?  Read or Ord?

Because of all these ambiguities during type checking ghc doesn't even
look at the constraint.  It would see instance Foo a, and instance Foo
(), and then say oh! those are overlapping instances because () could
apply to either class before you consider what constraints apply.

There's actually several very in depth answers on stackoverflow for
this questions like this, such as this one:
https://stackoverflow.com/a/3216937/1500583  It might give you some
ideas on what to do about this.

On Thu, Jun 29, 2017 at 1:15 PM, Silent Leaf <[hidden email]> wrote:
> hi,
>
> say i have the following typeclass:
>
> class Foo a where
>   bar :: a  -> String
>
> looks a lot like the Read typeclass, right? (at least i think it should?)
> well say it's a different meaning (in other terms i can't or do not want to
> use Read, but i'd like to implement a default version of bar for those
> instances that also implement Read. is there a way to do so?
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners



_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: special polymorphic default of typeclass depending on other typeclasses?

Silent Leaf
Sylvain Henri's link did the trick, that's what i was looking for (they call it generic implementation).

in terms of terminology, is there an intrinsic difference between generic and polymorphic?

2017-06-29 20:10 GMT+02:00 Silent Leaf <[hidden email]>:
typos in my previous message (including in the code), don't pay attention, any error is an error :P

2017-06-29 20:08 GMT+02:00 Silent Leaf <[hidden email]>:
you're right my example is more like Show, it's because i change two times the order of input and output, and did not check at the end if it was what i wanted...

Actually i did not mean constraints on instances, especially thereafter ad-hoc polymorphic instances.
I rather meant what i said, as in default implementation (as in, right inside the body of the class).
like that:

class Foo a where
  bar :: a -> String
  bar :: Show a => a -> String
  bar = show -- default implementation: in other terms, if you define an instance without defining this method

the idea would be then that if you have Foo (), you can either implement a special version, or leave it to show. mind you i'm not even sure we can define an instance without any specific implementation of method?

--that would be allowed:
instance Show => Foo () where
  -- nothing, if it's even legal by default

-- and of course that would be allowed to if someone wanted a special function bar :: Foo () => () -> String
instance Foo () where
  bar = ....

obviously, i do not mean *both* instances of Foo (), just, one or the other. it would merely be a way to implement ad-hoc polymorphism onto *default implementations of methods*, that is, those inside the body of the class.



2017-06-29 19:45 GMT+02:00 David McBride <[hidden email]>:
This is a common mistake that people who try to use type classes run
into.  I remember banging my head against it pretty hard when I first
started out.

There's this temptation that  you should be able to write the following:

class Foo a where
  bar :: a  -> String

instance Read a => Foo a where
  bar a = read a

instance Foo () where
  bar _ = "bar"

But the problem with that is that now () applies to two conflicting
classes.  It is both a Read and a Foo. So when you go bar (), which
instance should fire?  The Foo instance or the Read () => Foo
instance?

There are a multitude of ways you could try to resolve this.  Let's
say obviously the Read constrainted instance is more specific, we
should use that.  But then what if the user of your library happens to
have a instance Ord a => Foo a in his library, now which one of those
is more specific?  Read or Ord?

Because of all these ambiguities during type checking ghc doesn't even
look at the constraint.  It would see instance Foo a, and instance Foo
(), and then say oh! those are overlapping instances because () could
apply to either class before you consider what constraints apply.

There's actually several very in depth answers on stackoverflow for
this questions like this, such as this one:
https://stackoverflow.com/a/3216937/1500583  It might give you some
ideas on what to do about this.

On Thu, Jun 29, 2017 at 1:15 PM, Silent Leaf <[hidden email]> wrote:
> hi,
>
> say i have the following typeclass:
>
> class Foo a where
>   bar :: a  -> String
>
> looks a lot like the Read typeclass, right? (at least i think it should?)
> well say it's a different meaning (in other terms i can't or do not want to
> use Read, but i'd like to implement a default version of bar for those
> instances that also implement Read. is there a way to do so?
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners




_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Loading...