
Hi, Is it possible to model partial inheritance using Haskell type classes? For example, if the class Bird has a flying method can we represent Penguins as a sub-class of Bird without a flying method? Regards, Pat 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

On 17 July 2011 11:36, Patrick Browne
Hi, Is it possible to model partial inheritance using Haskell type classes? For example, if the class Bird has a flying method can we represent Penguins as a sub-class of Bird without a flying method?
Possibly with duck typing[1], but that's not vanilla Haskell type classes. FWIW I think you'd have to have: class (Flying a,Wings a,Feathers a,Beak a) => Bird a class (Wings a,Feathers a,Beak a) => Penguin a But I think that's nice anyway. Your functions, IMHO, should ask for only the properties of the object it needs, so: nomOnCorn :: Beak a => a -> Corn -> a nomOnCorn = ... Rather than nomOnCorn :: Bird a => a -> Corn -> a nomOnCorn = ... As there's no need to restrict yourself by having a Bird class, IMHO. I don't think the subclassing/hierarchy concept scales as well as a graph. [1]: http://chrisdone.com/posts/2010-11-22-duck-typing-in-haskell.html

Patrick Browne :
For example, if the class Bird has a flying method can we represent Penguins as a sub-class of Bird without a flying method?
The silliest - from the pedagogical perspective - answer to any question, is "you don't need it". But ... in most cases you really don't need it... When instancing your Bird class you may "forget" to define the flying methods. Is this unsuitable for you? The compiler will yell, but this is harmless. Jerzy Karczmarczuk PS. Penguins DO fly. http://www.telegraph.co.uk/news/worldnews/1583517/Flying-penguins-found-by-B...

Patrick Browne
Is it possible to model partial inheritance using Haskell type classes? For example, if the class Bird has a flying method can we represent Penguins as a sub-class of Bird without a flying method?
I'm not sure the question makes sense, if "fly" is a method of class Bird, then it can't also be a member of class Penguin. You can of course make instances of Bird without implementing the "fly" method (whether they are also instances of Penguin or not), or by implementing it as "undefined". -k -- If I haven't seen further, it is by standing in the footprints of giants

On 18/07/2011 13:52, Ketil Malde wrote:
I'm not sure the question makes sense, if "fly" is a method of class Bird, then it can't also be a member of class Penguin.
I am actually doing a language comparison and I was checking out a paper that said: "Type classes allow for partial inheritance, so that penguins can be birds without flying behavior." My question is concerned with the language constructs to do this rather than the semantic validity or desirability of such construct. But as pointed out by Jerzy my question is silly because can penguins can fly: On 17/07/2011 11:14, Jerzy Karczmarczuk wrote:
PS. Penguins DO fly. http://www.telegraph.co.uk/news/worldnews/1583517/Flying-penguins-found-by-B...
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

Patrick Browne :
I was checking out a paper that said: "Type classes allow for partial inheritance, so that penguins can be birds without flying behavior." ... as pointed out by Jerzy my question is silly because can penguins can fly ...
No, the question is not silly because of that crazy Adelie tribe. The question is doubtful, because the Haskell type classes is not an object-oriented system of classes, subclasses, etc. When you declare Rationals, you don't "inherit" the multiplication for them as Numbers. This "inheritance" you wish may manifest itself when you specify the *instances*. That's why I suggested how you might do that: for some datatypes, say the Emperors, you specify some special flying method (e.g. dummy or bombing), or you don't specify it at all. And the Emperors won't fly. Jerzy Karczmarczuk

On 18/07/2011 19:14, Jerzy Karczmarczuk wrote:
That's why I suggested how you might do that: for some datatypes, say the Emperors, you specify some special flying method (e.g. dummy or bombing), or you don't specify it at all. And the Emperors won't fly.
-- Here is my attempt data Emperor = Emperor data Robin = Robin class Bird a where fly :: a -> a -> a walk :: a -> a -> a instance Bird Robin where fly x y = y walk x y = x instance Bird Emperor where -- No fly method walk x y = y class (Bird a) => Penguin a where -- I do not think that I can override the walk method in the sub-class -- must be done in instance of Penguin instance Penguin Emperor where -- How can I override the walk method in the instance Penguin? -- walk x y = x Regards, Pat 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

Oh, I got it: You want to have:
class Bird b where
class Penguin p where
instance (Penguin b) => Bird b where
fly = -- fly method for penguins
2011/7/19 Patrick Browne
On 18/07/2011 19:14, Jerzy Karczmarczuk wrote:
That's why I suggested how you might do that: for some datatypes, say the Emperors, you specify some special flying method (e.g. dummy or bombing), or you don't specify it at all. And the Emperors won't fly.
-- Here is my attempt data Emperor = Emperor data Robin = Robin
class Bird a where fly :: a -> a -> a walk :: a -> a -> a
instance Bird Robin where fly x y = y walk x y = x
instance Bird Emperor where -- No fly method walk x y = y
class (Bird a) => Penguin a where -- I do not think that I can override the walk method in the sub-class -- must be done in instance of Penguin
instance Penguin Emperor where -- How can I override the walk method in the instance Penguin? -- walk x y = x
Regards, Pat
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@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Tue, 2011-07-19 at 01:13 +0200, Yves Parès wrote:
Oh, I got it: You want to have:
class Bird b where
class Penguin p where
instance (Penguin b) => Bird b where fly = -- fly method for penguins
I haven't followed the thread carefully but why does the bird have to be a penguin? ---------- As a side note - I agree with Christopher Done that the answer is that you shouldn't require for bird to fly. Regards

I haven't followed the thread carefully but why does the bird have to be a penguin?
A bird doesn't have to be a penguin :
*instance* (Penguin b) => Bird b where
fly = -- fly method for penguins
Says that every Penguin is a Bird.
But thinking back about it, there is a problem when trying to define the
method walk, because:
class Penguin p where
walkPenguin :: ....
instance (Penguin b) => Bird b where
fly = .....
walk = walkPenguin
is kind of awful, because walk has to be duplicated. So, not the best way to
go...
2011/7/19 Maciej Marcin Piechotka
On Tue, 2011-07-19 at 01:13 +0200, Yves Parès wrote:
Oh, I got it: You want to have:
class Bird b where
class Penguin p where
instance (Penguin b) => Bird b where fly = -- fly method for penguins
I haven't followed the thread carefully but why does the bird have to be a penguin?
----------
As a side note - I agree with Christopher Done that the answer is that you shouldn't require for bird to fly.
Regards
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On Tue, 2011-07-19 at 10:43 +0200, Yves Parès wrote:
I haven't followed the thread carefully but why does the bird have to be a penguin?
A bird doesn't have to be a penguin :
instance (Penguin b) => Bird b where fly = -- fly method for penguins
Says that every Penguin is a Bird. But thinking back about it, there is a problem when trying to define the method walk, because:
class Penguin p where walkPenguin :: ....
instance (Penguin b) => Bird b where fly = ..... walk = walkPenguin
is kind of awful, because walk has to be duplicated. So, not the best way to go...
Note to self: don't respond to ml after 2am. I saw instance but read class. Regards

On 19/07/2011, at 11:09 AM, Patrick Browne wrote:
data Emperor = Emperor data Robin = Robin
class Bird a where fly :: a -> a -> a walk :: a -> a -> a
instance Bird Robin where fly x y = y walk x y = x
instance Bird Emperor where -- No fly method walk x y = y
Note that "no 'fly' method is visibly presented" is not at all the same thing as "no 'fly' method EXISTS". From the report: "The default class method for v sub i is used if no binding for it is given in a particular instance declaration (see Section 4.3.2)." so the absence of a method in 'instance Bird Emperor' doesn't mean that it doesn't _have_ one, just that it inherits the default class method.

On 19/07/2011, at 0:09, Patrick Browne
instance Bird Emperor where -- No fly method walk x y = y
instance Penguin Emperor where -- How can I override the walk method in the instance Penguin? -- walk x y = x
Why would you want to override the walk method for Emperor? It already has one due to being a Bird. How could you possibly distinguish an Emperor walking as a Bird from an Emperor walking as a Penguin? Why would it be desirable?

On Mon, Jul 18, 2011 at 3:14 PM, Jerzy Karczmarczuk
That's why I suggested how you might do that: for some datatypes, say the Emperors, you specify some special flying method (e.g. dummy or bombing), or you don't specify it at all. And the Emperors won't fly.
Instead of flying, they'll throw exceptions around. =/ -- Felipe.

On 19/07/2011, at 5:09 AM, Patrick Browne wrote:
On 18/07/2011 13:52, Ketil Malde wrote:
I'm not sure the question makes sense, if "fly" is a method of class Bird, then it can't also be a member of class Penguin.
I am actually doing a language comparison and I was checking out a paper that said: "Type classes allow for partial inheritance, so that penguins can be birds without flying behavior."
That would be "An Image-Schematic Account of Spatial Categories"
by Werner Kuhn, I take it? His e-mail address is at the top of
the paper, so why not ask him? I cannot find anything in the
Haskell 2010 report that says anything about partial inheritance.
In his example,
class BUILDING building where
But as pointed out by Jerzy my question is silly because can penguins can fly: On 17/07/2011 11:14, Jerzy Karczmarczuk wrote:
PS. Penguins DO fly. http://www.telegraph.co.uk/news/worldnews/1583517/Flying-penguins-found-by-B...
And what a fine April Fool's joke that was. But even in that joke, flying was something "no other penguins can do".

Quoth "Richard O'Keefe"
class BUILDING building where
class BUILDING house => HOUSE house where any instance of HOUSE *will* have in its interface everything that any instance of BUILDING will.
But ... for those who might be overly influenced by a superficial similarity to OOP here ... the idea that the above relationship makes House a subclass of Building isn't really a natural way to look at it. It's true that a House instance will also "have in its interface everything that any instance of Building will", but only because the programmer is constrained to do that. To consider the whole outline: class Building building where ... specify the behavior of buildings here, if any class Building house => House house where ... specify additional behavior of houses here, if any data Shed = Shed "shed" instance Building Shed where ... define Building functions for Shed instance House Shed where ... define House functions for Shed The Building => House constraint doesn't add anything, it just checks that each instance of House also is an instance of Building. If you omit this constraint, everything will work the same - even the constraint will still be there, implicitly, albeit not at the same level. To me, it's somewhat misleading to use words like "inheritance" and "subclass" for the relationship between Building and House, unless there's some feature of the system I missed. Donn
participants (11)
-
Christopher Done
-
Donn Cave
-
Felipe Almeida Lessa
-
Jerzy Karczmarczuk
-
Ketil Malde
-
Maciej Marcin Piechotka
-
Maciej Piechotka
-
Malcolm Wallace
-
Patrick Browne
-
Richard O'Keefe
-
Yves Parès