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 showable 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

Popular posts from this blog

curl - PHP fsockopen help required -

HTTP/1.0 407 Proxy Authentication Required PHP -

c# - Resource not found error -