Lets assume I have a type class Stack
with one instance List
:
class Stack a where
push :: a -> Integer -> a
pop :: a -> a
last :: a -> Integer
data List = Empty | Element Integer List
instance Stack List where
push list value = Element value list
pop Empty = error "No elements"
pop (Element _ list) = list
last Empty = error "No elements"
last (Element value _) = value
How Stack
has to be defined in order for List
to not be limited to Integer
values?
-- class Stack (?) where ...
data List a = Empty | Element a (List a)
-- instance Show (List a) where ...
Multiple parametersYou can also use more than one type parameter in generics in Java, you just need to pass specify another type parameter in the angle brackets separated by comma.
Yes - it's possible (though not with your method signature) and yes, with your signature the types must be the same.
Generic Classes As with generic methods, the type parameter section of a generic class can have one or more type parameters separated by commas. These classes are known as parameterized classes or parameterized types because they accept one or more parameters.
A type parameter can have multiple bounds.
Consider using a higher-kinded class variable. Thus:
class Stack s where
push :: s a -> a -> s a
pop :: s a -> s a
last :: s a -> a
data List a = Empty | Element a (List a)
The instance remains exactly as you wrote it (though List
now has kind * -> *
instead of *
):
instance Stack List where
push list value = Element value list
pop Empty = error "No elements"
pop (Element _ list) = list
last Empty = error "No elements"
last (Element value _) = value
This approach is pure Haskell 2010 -- it requires no extensions.
Also, consider making your failures observable; for instance by changing the type of pop
and last
to return Maybe (s a)
and Maybe a
, respectively.
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