haskell - What "Contraint is no smaller than the instance head" means and how to solve it -
i write like:
{-# language flexiblecontexts,flexibleinstances #-} import data.bytestring.char8 (bytestring,pack) import data.foldable (foldable) class (show a) => rows rrepr :: -> [bytestring] rrepr = (:[]) . pack . show instance (foldable f,show (f a)) => rows (f a) rrepr = const []
meaning f a
instantiate rows
if f
instantiate foldable
, f a
instantiate show
. when run ghc get:
constraint no smaller instance head in constraint: show (f a) (use -xundecidableinstances permit this) in instance declaration `rows (f a)'
i have 2 questions:
- what "smaller" means in error , problem?
- what right way define want without using
undecidableinstances
?
let's play compiler: have type (f a)
we'd see if valid satisfier of rows
constraint. so, need dispatch proof (f a)
satisfies show (f a)
well. isn't problem unless writes an
instance rows (f a) => show (f a) ...
in case i'm began. encoding infinite loop sort of foolish, haskell statically ensures it's impossible unless ask undecidableinstances
.
normally haskell ensures each step of "resolution chase" reduces size of type @ least 1 constructor. leads simple proof structural induction we'll end bare type in finite number of resolutions.
this overly restrictive, instance resolution steps meaningful, useful, , total if don't reduce constructor tree. same kind of totality restriction applies in languages agda , coq , it's bit of illustrative challenge manipulate algorithm 1 proceeds structural induction.
so how can fix it? 1 way lose show
constraint on class
definition use instance show1
prelude-extras.
class show1 f ... show1 :: (show1 f, show a) => f -> string -- not instance definition!
and have instance (foldable f, show1 f, show a) => rows (f a) ...
works in testing. can write default instance standalone function.
defrrepr :: show => -> [bytestring] defrrepr = (:[]) . pack . show
and use whenever writing instance definition show
able thing.
the other solution use newtype
wrappers allow haskell see "layer" of resolution has been removed.
instance (foldable f, show (f a)) => rows (foldablerow f a) rrepr = const [] . unfr newtype foldablerow f = fr { unfr :: f } deriving (show)
Comments
Post a Comment