[Haskell-cafe] Subclass or no subclass?

Richard Eisenberg eir at cis.upenn.edu
Sun Jun 30 22:00:01 CEST 2013


It sounds like the following example may help:

> class A alpha where
>   a :: alpha -> Int
>
> class A beta => B beta where
>   b :: beta -> Int
>
> class C gamma where
>   c :: gamma -> Int
>
> foo :: B beta => beta -> Int
> foo x = a x + b x
> -- the (A beta) is implied by the superclass constraint)
>
> bar :: C gamma => gamma -> Int
> bar x = a x + c x
> -- ERROR: no instance of A gamma

The superclass constraint A beta => B beta means that anywhere a B beta constraint is written, the constraint A beta is inferred. For this all to work out, it also means that any instance of B must be coupled with an instance for A.

Does this help clarify?

Richard

On Jun 30, 2013, at 1:46 PM, Patrick Browne wrote:

> As you say if I omit references to superclass methods in the subclasses then I get different compile time behaviour.
> But then the question is that if a putative subclass has no reference to superclass methods should it be a subclass at all?
> I deliberately want to model the case where each subclass depends on the superclass.
> Hence, I have arranged that each subclass method calls a superclass method. 
> If I remove the references to the superclass methods would that indicate that I do not need the superclass?
> It seems that if a method is invoked in a class instance then there must exist a definition of that method somewhere (not necessarily in the class/instance hierarchy). 
> Where there exists a genuine sub/super relation, is there a case where the compiler will not catch the implicit superclass (WithoutSubclass)  and *must* have the explicit class hierarchy (WithoutSubclass).
> 
> The above represents my attempts to understand the semantics of Haskell sub/super-classes. I may have missed something obvious.
> Thanks,
> Pat
> 
> On 29/06/13, Richard Eisenberg <eir at cis.upenn.edu> wrote:
>> 
>> Yes, the runtime behavior should be the same between those modules. But, the "compile-time behavior" is not. The superclass constraints  in your first version mean that every instance of, say, Building *must* be accompanied by an instance of "Shelter", regardless of the implementation of that instance. This would be easiest to see if your implementations did not call any functions, but just returned strings. With that change, in your second version, you could remove the instance for Shelter and everything would still compile. However, in the first, removing that instance would cause compile-time failures for the others, as the superclass constraint would not be satisfied.
>> 
>> I hope this helps!
>> Richard
>> 
>> On Jun 29, 2013, at 12:46 PM, Patrick Browne wrote:
>> 
>>> Hi,
>>> The runtime behaviour of the two modules below *seems* to be the same.
>>> Is this correct? 
>>> I am not trying to say "every building is a shelter", rather "anything that is a building must provide sheltering services".
>>> I think that the use of sub-classes makes this explicit, but it *seems* that one gets the same results without the subclass.
>>> Any clarification welcome.
>>> 
>>> Regards,
>>> Pat
>>> 
>>> -- ========================================
>>> module WithSubclass where
>>> data SomeWhereToShelter = SomeWhereToShelter 
>>> class Shelter shelter where
>>>  s :: shelter -> String
>>> class Shelter building => Building building where
>>>  b :: building -> String
>>> class Shelter house => House house where
>>>  h :: house -> String
>>> 
>>> instance Shelter SomeWhereToShelter where
>>>  s x = "Shelters afford basic sheltering"  
>>> instance Building SomeWhereToShelter where
>>>  b x =  (s x) ++ ", Buildings afford better sheltering"
>>> instance House SomeWhereToShelter where
>>>  h x = (s x) ++ (b x) ++  ", Houses afford even better sheltering"
>>> 
>>> 
>>> -- =======================================
>>> module WithoutSubclass where
>>> data SomeWhereToShelter = SomeWhereToShelter 
>>> 
>>> class Shelter shelter where
>>>  s :: shelter -> String
>>> class Building building where
>>>  b :: building -> String
>>> class House house where
>>>  h :: house -> String
>>> 
>>> instance Shelter SomeWhereToShelter where
>>>  s x = "Shelters afford basic sheltering"  
>>> instance Building SomeWhereToShelter where
>>>  b x =  (s x) ++ ", Buildings afford better sheltering"
>>> instance House SomeWhereToShelter where
>>>  h x = (s x) ++ (b x) ++  ", Houses afford even better sheltering"
>>> 
>>> Tá an teachtaireacht seo scanta ó thaobh ábhar agus víreas ag Seirbhís Scanta Ríomhphost de chuid Seirbhísí Faisnéise, ITBÁC agus meastar í a bheith slán. http://www.dit.ie
>>> This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. http://www.dit.ie _______________________________________________
>>> Haskell-Cafe mailing list
>>> Haskell-Cafe at haskell.org <Haskell-Cafe at haskell.org>
>>> http://www.haskell.org/mailman/listinfo/haskell-cafe
>> 
> 
> Tá an teachtaireacht seo scanta ó thaobh ábhar agus víreas ag Seirbhís Scanta Ríomhphost de chuid Seirbhísí Faisnéise, ITBÁC agus meastar í a bheith slán. http://www.dit.ie
> This message has been scanned for content and viruses by the DIT Information Services E-Mail Scanning Service, and is believed to be clean. http://www.dit.ie

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/haskell-cafe/attachments/20130630/ee66ac65/attachment.htm>


More information about the Haskell-Cafe mailing list