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