gpt4 book ai didi

Haskell 实例 : how could this be some valid code?

转载 作者:行者123 更新时间:2023-12-03 15:27:00 25 4
gpt4 key购买 nike

在我编写 Show 实例的一个小例子时,我犯了一个缩进错误:

module Main where

data B= B0|B1

instance Show B where
show B0="0"
show B1="1"


main=print B0
显然,工作代码是:
module Main where

data B= B0|B1

instance Show B where
show B0="0"
show B1="1"


main=print B0
我原以为第一个会出现编译错误,但我可以运行它,结果是: example.hs: stack overflow为什么这段代码甚至可以编译?
另外,为什么这只是运行时错误(如果堆栈不受约束,则会填满您的 RAM)而不是编译错误?

最佳答案

instance的 body 可以为空。您可以省略 where条款:

instance Show B
但你也可以包括它:
instance Show B where
-- nothing here
这对于为方法提供默认实现的类型类很有用,可能基于泛型编程工具。例如,使用 aeson包中,定义实例与 JSON 之间的转换的常用方法是使用泛型和空实例:
{-# LANGUAGE DeriveGeneric #-}

import GHC.Generics

data Person = Person {
name :: Text
, age :: Int
} deriving (Generic, Show)

-- these empty instances use Generics to provide a default implementation
instance ToJSON Person
instance FromJSON Person
在你的程序中,通过省略缩进,你定义了一个 instance Show B没有方法定义(并且 -Wall 会生成“缺少方法”警告,告诉您它不满足实例的最低要求)。无缩进 show正在为 show 提供新的顶级定义,与 show无关在 Show类型类。
您还没有用过 show明确地。相反,您已经通过 print 隐式使用了它,它总是调用 show从类型类中,忽略您的顶级定义,因此您的崩溃程序相当于:
data B = B0 | B1
instance Show B
main = print B0
这会产生堆栈溢出,因为存在 show 的默认定义。和 showsPrec在没有给出特定实例时使用:
show x = shows x ""
showsPrec _ x s = show x ++ s
与顶级函数 shows 一起运行(不是类型类的一部分):
shows = showsPrec 0
当至少有 show 之一时,这很有效。或 showsPrec在实例中定义,然后另一个得到一个合理的定义,但如果两者都没有定义,这会在这三个函数之间创建一个无限递归循环。
另外,请注意以下程序会告诉您 show是模棱两可的,这将使发生的事情更清楚。
module Main where

data B= B0|B1

instance Show B where
show B0="0"
show B1="1"

main=putStrLn (show B0) -- instead of print

关于Haskell 实例 : how could this be some valid code?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65692148/

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