haskell - GHC uses catch-all instance if constraint is missing? -
i've been experimenting simple implementation of hlists , function hasint returns true if int member of list:
{-# language flexibleinstances #-} data hnil = hnil deriving (show, read) data hcons b = hcons b deriving (show, read) class hasint hasint :: -> bool instance hasint hnil hasint _ = false instance hasint => hasint (hcons as) hasint (hcons as) = (isint a) || (hasint as) class isint isint :: -> bool instance isint int isint _ = true instance {-# overlappable #-} isint isint _ = false 3 = 3 :: int main = putstrln $ "isint 3 = " ++ show (isint three) -- true putstrln $ "isint true = " ++ show (isint true) -- false print $ hasint $ hcons 3 $ hcons true hnil -- false ??? this doesn't give expected results. however, seem work if change:
instance hasint => hasint (hcons as) to:
instance (isint a, hasint as) => hasint (hcons as) on other hand, expect ghc complain if use type class function don't include constraint, , don't such indication in case.
clearly has catch-all instance isint a. could not deduce (isint a) arising use of 'isint' error if replace catch-all instance with:
instance isint bool isint _ = false instance isint hnil isint _ = false my question is: expected behavior of ghc - silently use catch-all instance if there no explicit type class constraint?
yes, expected behavior. if write
instance foo you declaring types instances of foo, , ghc believes you.
this 100% analogous following:
foo :: int -> bool foo x = x > 0 even though don't have ord int in context, ghc knows there such instance. likewise, in:
bar :: -> b bar x = {- use foo instance x here -} even though don't have foo a in context, ghc knows there such instance.
Comments
Post a Comment