Reputation: 177
I haven't found any good examples of this kind of situations.
I have this kind of datatypes and a class with instances:
data Type1 = Const1 | Const2
deriving Show
data Type2 = Type2 Int
deriving Show
class Class a where
function :: a -> Int
instance Class Type1 where
function Const1 = 2
function Const2 = 3
instance Class Type2 where
function (Type2 x) = x * 2
Should add instances that can compute this way:
function [Just (Const2), Nothing, Just (Const1)]
function [Nothing, Nothing, Just (Type2 1), Just (Type2 2)]
Is there a way to do this something like this?
instance Class (Maybe a) where
function Nothing = 0
function (Just x) = function x <--- gives an error
instance Class [a] where
function [] = 0
function [x] = function x <--- error
function (x:sx) = function x + function xs <--- error
Upvotes: 2
Views: 608
Reputation: 17796
You need to say this:
instance Class a => Class (Maybe a) where ....
and likewise
instance Class a => Class [a] where ...
This means that Maybe a
is only an instance if a
is, and likewise for [a]
. This in turn lets you use function a
in the implementations.
Upvotes: 2
Reputation: 477598
This only works if a
is a member of the Class
typeclass, so you need to add that as a constraint:
-- ↓ add a typeconstraint
instance Class a => Class (Maybe a) where
function Nothing = 0
function (Just x) = function x
-- ↓ add a typeconstraint
instance Class a => Class [a] where
function [] = 0
function [x] = function x
function (x:xs) = function x + function xs
Indeed, you write for example function (Just x) = function x
, but that only works if function x
makes sense, and that is the case of a
(the type wrapped by Maybe
), is an instance of the Class
typeclass.
We then can determine the function
of the sample lists:
Prelude> function [Just (Const2), Nothing, Just (Const1)]
5
Prelude> function [Nothing, Nothing, Just (Type2 1), Just (Type2 2)]
6
Upvotes: 3