gpt4 book ai didi

haskell - 手动实例显示定义导致堆栈空间溢出

转载 作者:行者123 更新时间:2023-12-02 16:48:40 25 4
gpt4 key购买 nike

当我手动为 PhisicalCell 数据类型编写一个简单的显示实例时,程序会消耗所有空间。当派生他自己的 Show 版本时,这种情况不会发生。为什么?

这是我正在编写的代码的精简版本:

import Data.Array

type Dimensions = (Int, Int)
type Position = (Int, Int)
data PipeType = Vertical | Horizontal | UpLeft | UpRight | DownLeft | DownRight deriving (Show)

data PhisicalCell = AirCell
| PipeCell PipeType
| DeathCell
| RecipientCell Object
-- deriving (Show) SEE THE PROBLEM BELOW

data Object = Pipe { pipeType :: PipeType -- tipo di tubo
, position :: Position -- posizione del tubo
, movable :: Bool -- se posso muoverlo
}
| Bowl { position :: Position -- posizione dell'angolo in alto a sinistra
, dimensions :: Dimensions -- dimensioni (orizzontale, verticale)
, waterMax :: Int -- quanta acqua puo' contenere al massimo
, waterStart :: Int -- con quanta acqua parte
, hatch :: Maybe Position -- un eventuale casella di sbocco
, sourceIn :: [Position] -- posti da cui l'acqua entra
, movable :: Bool -- se posso muoverlo
}
| Death
deriving (Show)

data Level = Level Dimensions [Object]
type LevelTable = Array Dimensions PhisicalCell

-- HERE IS THE PROBLEM --
instance Show PhisicalCell where
show AirCell = " "
show (PipeCell _) = "P"
show DeathCell = "X"
show (RecipientCell _) = "U"

both :: (a -> b) -> (a,a) -> (b,b)
both f (a,b) = (f a, f b)

levelTable :: Level -> LevelTable
levelTable (Level dim _) = initial
where initial = array ((0,0), both (+1) dim) $
[((x,y), AirCell) | x <- [1..fst dim], y <- [1..snd dim] ]
++ [((x,y), DeathCell) | x <- [0..fst dim + 1], y <- [0, snd dim + 1]]
++ [((x,y), DeathCell) | x <- [0, fst dim + 1], y <- [0..snd dim + 1]]

main = print $ levelTable (Level (8,12) [])

最佳答案

The Show type class has mutually referencing default implementations :

class  Show a  where
-- | Convert a value to a readable 'String'.
--
-- 'showsPrec' should satisfy the law
-- ...
...
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

因此,如果您声明一个 Show 实例而不定义任何方法

instance Show where

nextNewFunction :: Bla
...

GHC 会很乐意编译所有默认的,所以不会有任何错误。然而,一旦您尝试使用它们中的任何一个,您就会陷入与您的对象一样致命的循环中......并且相互递归最终将破坏堆栈。

现在,您的代码看起来不太像是有这样一个空的 instance Show 声明,但实际上您确实如此:由于缩进错误,show > 您定义的那里被识别为一个新的免费顶级函数,只是碰巧与 GHC.Show.show 具有相同的名称。您可以添加

show :: PhisicalCell -> String

复制到您的文件并获得与现在相同的结果。

关于haskell - 手动实例显示定义导致堆栈空间溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18893391/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com