For example, I have a type class :
class MyClass a b c where
fun01 :: a -> b
fun02 :: a -> c
fun03 :: a -> b -> c -> ()
fun04 :: a -> WhatEver
I'd like to provide a default implementation for my, let's call it BaseDataType
which defines implementations of fun03
in terms of it self and fun01
and fun02
. Then I'd have something like this :
class MyClass BaseDataType b c where
fun03 = fun01 <$> fun02 ...
fun04 = fun02 ...
And than to finalize my class instance and avoid all the boilerplate code for fun03
and fun04
I'd just provide fun01
and fun02
like this :
instance MyClass BaseDataType Int Char where
fun01 = 1
fun02 = 'C'
Is there possibly some language extension that allows this kind of behaviour? I couldn't find anything on this topic.
There is no such extension, but you can achieve this functionality simply by splitting your class into two classes:
class MyClass1 a b c where
fun03 :: a -> b -> c -> ()
fun04 :: a -> WhatEver
class MyClass1 a b c => MyClass2 a b c where
fun01 :: a -> b
fun02 :: a -> c
Then your instances will work the way you want:
-- NB: need the MyClass2 constraint if you use `fun01` or `fun02` in the definitions
-- This requires UndecidableInstances
instance MyClass2 BaseDataType b c => MyClass1 BaseDataType b c where
fun03 = fun01 <$> fun02 ...
fun04 = fun02 ...
instance MyClass2 BaseDataType Int Char where
fun01 = 1
fun02 = 'C'
Users of your class are not affected; they can continue to consume MyClass2
where they used MyClass
before and get the exact same functionality.
Aside: the original definition of MyClass
, and MyClass1
and MyClass2
don't even compile due to several ambiguous type errors (c
is not mentioned in the type of fun01
, etc.) - I assume this class was defined just for demonstration purposes and I haven't tried to fix this.
You can use DefaultSignatures like this
class MyClass a b c where
fun01 :: a -> b
fun02 :: a -> c
fun03 :: a -> b -> c -> ()
default fun03 :: (a ~ BaseDataType) => a -> b -> c -> ()
fun03 = fun01 <$> fun02 ...
fun04 :: a -> WhatEver
default fun04 :: (a ~ BaseDataType) => a -> WhatEver
fun04 = fun02 ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With