Haskell: class instance with class type parameters -


good day. i'm new haskell. 1 thing not clear me concerning declaring , instantiating custom classes.

  1. there standard class integral in haskell. according hackage, integral declares mandatory method quot :: -> -> a. means every instance of class should have method implementation, right?

  2. we can declare function, using integral argument, like:

proba :: (integral a) => -> -> proba x y = x `quot` y 

so far good

  1. 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

Popular posts from this blog

javascript - how to protect a flash video from refresh? -

android - Associate same looper with different threads -

visual studio 2010 - Connect to informix database windows form application -