簡體   English   中英

為什么這個Haskell代碼會產生堆棧溢出?

[英]Why does this Haskell code produce a stack overflow?

我第一次和Haskell一起玩。 我寫了這三行,期望得到編譯器錯誤,但在ghci鍵入它會導致堆棧溢出。

$ 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

誰能解釋這種行為?

您沒有定義實例的方法。 show的默認值使用showPrec (通過shows ), showPrec的默認值使用show 所以你有一個循環定義,最終會明顯溢出堆棧。 也許你打算派生一個實例?

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

編輯:清除instance任何問題並deriving

鍵入instance ,意味着“我將定義自己的實例或利用類型類的默認代碼”:

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

當您在數據聲明后鍵入deriving ,編譯器將自動為您的類型生成合理的實例:

data MyType = OneOrMoreConstructors deriving (Show)

如果您或其他程序員沒有派生出所需的實例而您不想編寫自己的實例,那么您可以使用獨立派生,這會產生與使用deriving相同的結果,但可能在不同的模塊中使用它自己的行:

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

較新的GHC在那里發出警告:

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

如您所見,您沒有為必要的方法定義實現,並且方法的默認實現會導致無限遞歸,從而導致堆棧溢出。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM