Can subclass override its super-class' default implementation of a function?

I'm not sure if this is possible at all. I'd like to do something like this: class A a where foo :: a -> Double foo a = 5.0 class (A a) => B a where foo a = 7.0 data Blah = Blah data Bar = Bar instance A Blah instance B Bar let blah = Blah bar = Bar foo blah -- should print out 5 foo bar -- should print out 7 Basically, I have a bunch of instances that have a common functionality but I'd like to be able to group those instances and give each group a different default implementation of that functionality. It's so easy to do this in Java, for example, but I have no idea how to do it in Haskell. The above example will not compile, btw. Thanks a lot -- View this message in context: http://www.nabble.com/Can-subclass-override-its-super-class%27-default-imple... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

siki wrote:
I'm not sure if this is possible at all. I'd like to do something like this:
class A a where foo :: a -> Double
foo a = 5.0
class (A a) => B a where foo a = 7.0
This is currently not possible in Haskell. It's been proposed, though: http://haskell.org/haskellwiki/Class_system_extension_proposal If you have an actual example we might be able to come up with a different way of modelling it so that it does what you want, though. Martijn.

The actual problem is quite similar to the one that I provided or to the one in the description of the proposed extension that you linked. Someone on another forum suggested record functions but I'm not sure I understood correctly how that would work around this problem. Any suggestion is greatly appreciated! Thanks, -Gabor Martijn van Steenbergen-2 wrote:
siki wrote:
I'm not sure if this is possible at all. I'd like to do something like this:
class A a where foo :: a -> Double
foo a = 5.0
class (A a) => B a where foo a = 7.0
This is currently not possible in Haskell. It's been proposed, though:
http://haskell.org/haskellwiki/Class_system_extension_proposal
If you have an actual example we might be able to come up with a different way of modelling it so that it does what you want, though.
Martijn.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- View this message in context: http://www.nabble.com/Can-subclass-override-its-super-class%27-default-imple... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

Quoth siki
The actual problem is quite similar to the one that I provided or to the one in the description of the proposed extension that you linked.
Someone on another forum suggested record functions but I'm not sure I understood correctly how that would work around this problem. Any suggestion is greatly appreciated!
Maybe it was function records. That's kind of the poor man's OOP in Haskell - no typeclasses needed. data FileRec = FileRec { fileRecRead :: Int -> IO String , fileRecWrite :: String -> IO () } socketFileRec socket = { fileRecWrite = \ s -> send socket s 0 , fileRecRead = \ i -> recv socket i 0 } pipeFileRec p0 p1 = { fileRecWrite = writeFd p1 , fileRecRead = readFd p0 } echoBlock file count = (fileRecRead file) count >>= fileRecWrite file Maybe you could use that, maybe you couldn't. That's why Martin suggested that you reveal the actual problem. Not the solution you had in mind, but the thing you're trying to solve. Donn

No, but functionality similar to this has been proposed several times, under the name "Class Aliases" [1]. The big problem is in the definition of B: class (A a) => B a where ... In this case, you must make something an instance of A before it can be an instance of B, and, in order to make something an instance of A, you must provide an implementation of "foo". Not providing an implementation is the same as providing the default. With the class alias proposal you would write
class B a = A a where foo a = 7.0
In this case, (B a) and (A a) are the same class, but provide
different default implementations for the methods. So you *cannot*
declare something an instance of both B and A. But if you declare
something an instance of B without providing an implementation of
"foo", it would use B's default, whereas instances of A would use A's
default.
Unfortunately, I don't believe anyone is working on implementing this
proposal. It's high on my list of "desired features", but I think
that not all the details have been figured out with how it interacts
with other features of the language.
-- ryan
[1] http://repetae.net/recent/out/classalias.html,
http://haskell.org/haskellwiki/Class_alias
On Mon, Apr 27, 2009 at 2:00 PM, siki
I'm not sure if this is possible at all. I'd like to do something like this:
class A a where foo :: a -> Double
foo a = 5.0
class (A a) => B a where foo a = 7.0
data Blah = Blah data Bar = Bar
instance A Blah instance B Bar
let blah = Blah bar = Bar
foo blah -- should print out 5 foo bar -- should print out 7
Basically, I have a bunch of instances that have a common functionality but I'd like to be able to group those instances and give each group a different default implementation of that functionality. It's so easy to do this in Java, for example, but I have no idea how to do it in Haskell. The above example will not compile, btw.
Thanks a lot -- View this message in context: http://www.nabble.com/Can-subclass-override-its-super-class%27-default-imple... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Basically, I have a bunch of instances that have a common functionality but I'd like to be able to group those instances and give each group a different default implementation of that functionality. It's so easy to do this in Java, for example, but I have no idea how to do it in Haskell. The above example will not compile, btw.
Before going into language extensions, is there anything wrong with: class C a where foo :: a -> Double fooA a = 5.0 --default A fooB a = 7.0 -- default B data Blah = Blah data Bar = Bar instance C Blah where foo = fooA instance C Bar where foo = fooB blah = Blah bar = Bar main = do print $ foo blah -- should print out 5 print $ foo bar -- should print out 7 It seems to match your spec. Claus

On Mon, Apr 27, 2009 at 11:00 PM, siki
I'm not sure if this is possible at all. I'd like to do something like this:
class A a where foo :: a -> Double
foo a = 5.0
class (A a) => B a where foo a = 7.0
I probably don't understand the question properly, but I don't see why you would need another class here. Why not : module Main where class A a where foo :: a -> Double foo _ = 5.0 data Blah = Blah data Bar = Bar instance A Blah instance A Bar where foo _ = 7.0 blah = Blah bar = Bar main = do print $ foo blah -- prints 5.0 print $ foo bar -- prints 7.0
participants (6)
-
Claus Reinke
-
david48
-
Donn Cave
-
Martijn van Steenbergen
-
Ryan Ingram
-
siki