简体   繁体   中英

Why does this Haskell code produce a stack overflow?

I'm playing around with Haskell for the first time. I wrote these three lines, expecting to get a compiler error, but typing it inside ghci results in a stack overflow.

$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> data ImNewToHaskell = AndWhatIsThis
Prelude> instance Show ImNewToHaskell
Prelude> show AndWhatIsThis
"*** Exception: stack overflow

Can anyone explain this behavior?

You didn't define the methods of the instance. The default for show uses showPrec (via shows ) and the default for showPrec uses show . So you have a cyclic definition which will clearly overflow the stack eventually. Perhaps you intended to derive an instance?

Prelude> data ImNewToHaskell = AndWhatIsThis deriving (Show)
Prelude> show AndWhatIsThis
"AndWhatIsThis"

EDIT: Clearing up any issues with instance and deriving :

When you type instance is means "I am going to define my own instance or leverage the type class's default code":

instance Show Foo where
    show Foo = "This is the string representing Foo"

When you type deriving after a data declaration then the compiler will automatically generate a sensible instance for your type:

data MyType = OneOrMoreConstructors deriving (Show)

If you, or another programmer, did not deriving a desired instance and you do not desire to write your own then you can use standalone deriving, which yields the same result as using deriving but on its own line likely in a different module:

{-# LANGUAGE StandaloneDeriving #-}
deriving instance Show MyType

Newer GHC's emits a warning there:

λ> data ImNewToHaskell = AndWhatIsThis
λ> instance Show ImNewToHaskell

<interactive>:108:10: Warning:
    No explicit implementation for
      either ‘showsPrec’ or ‘show’
    In the instance declaration for ‘Show ImNewToHaskell’
λ> show AndWhatIsThis
"*** Exception: stack overflow

As you can see, you aren't defining an implementation for methods necessary, and the default implementations of the methods cause infinite recursion and therefore stack overflow.

class  Show a  where
    showsPrec :: Int -> a -> ShowS
    show      :: a   -> String
    showList  :: [a] -> ShowS

    showsPrec _ x s = show x ++ s
    show x          = shows x ""
    showList ls   s = showList__ shows ls s

shows           :: (Show a) => a -> ShowS
shows           =  showsPrec 0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM