Haskell: class instance with class type parameters -
good day. i'm new haskell. 1 thing not clear me concerning declaring , instantiating custom classes.
there standard class
integral
in haskell. according hackage,integral
declares mandatory methodquot :: -> -> a
. means every instance of class should have method implementation, right?we can declare function, using integral argument, like:
proba :: (integral a) => -> -> proba x y = x `quot` y
so far good
- now lets declare our own class proba:
class proba proba :: -> ->
i can implement int or integer (or other data type) instance this:
instance proba integer proba x y = x `quot` y instance proba int proba x y = x `quot` y
but don't want to. i want 1 instance every integral. when try it, error:
instance (integral a) => proba proba x y = x `quot` y illegal instance declaration `proba a' (all instance types must of form (t a1 ... an) a1 ... *distinct type variables*, , each type variable appears @ once in instance head. use flexibleinstances if want disable this.) in instance declaration `proba a'
ok, seems asks me distinct type variables instead of classes. why?! why isn't enough have integral
here? since quot
declared every integral
, instance should valid every integral
, shoudn't it?
maybe there way achieve same effect?
as error message indicates, can use flexibleinstances
(a common , safe extension) allow behavior, you'll need undecidableinstances
:
{-# language flexibleinstances #-} {-# language undecidableinstances #-} class proba proba :: -> -> instance integral => proba proba = quot
the reason why isn't enabled default because it's ghc extension, , not part of haskell98 specification. you'll find there lot of language extensions useful , safe use, , times want them enabled in particular modules. instead of asking "why isn't default", ask "when not want default?".
another way implement without extensions encode type class directly data type:
data proba = proba { proba :: -> -> } integralproba :: integral => proba integralproba = proba quot
then can pass around as
foldproba :: proba -> -> [a] -> foldproba p = foldr (proba p)
then if have foldproba integralproba
, automatically constrains type integral => -> [a] -> a
.
Comments
Post a Comment