我无法为自定义数据类型定义Show
的实例。
data Circle = Circle { x::Float, y::Float, r::Float }
instance Show Circle where
show :: Circle -> String
show circle = concat $
intersperse "," (map Prelude.show [x circle, y circle, r circle])
这一切都存在于一个名为Main.
的模块中,对某些Circle Main.show circ
调用circ
会导致堆栈溢出异常。为什么GHC将Prelude.show
的合格用法解释为对我在此处定义的函数的调用?
答案 0 :(得分:7)
这是一个缩进问题。这是更正:
data Circle = Circle { x::Float, y::Float, r::Float }
instance Show Circle where
-- Illegal syntax
-- show :: Circle -> String
show circle = concat $
intersperse "," (map show [x circle, y circle, r circle])
当您忘记缩进时,您将获得两个单独的声明:
instance Show Circle where { }
一个功能:
show :: Circle -> String
让我们忽略这个函数,因为它永远不会被调用。定义空类实例时,将获得函数的默认定义。这将传递Haskell类型检查器,因为show
默认使用showsPrec
,而showsPrec
默认使用show
。如果覆盖这两种方法中的一种或两种,则会得到Show
的工作实例。如果不重写,则默认实现将相互递归并溢出堆栈。
Prelude.show
上述代码中只有一个show
,即Prelude.show
。实现类时,您没有实现名为“show”的 new 函数,但是您正在为泛型函数Prelude.show
提供新的实现。
答案 1 :(得分:0)
我们还可以使用InstanceSigs
扩展名来在实例中使用签名。
不要忘记在“where
”中使用空格。
{-# LANGUAGE InstanceSigs #-}
data Circle = Circle { x::Float, y::Float, r::Float }
instance Show Circle where
show :: Circle -> String
show circle = concat $
intersperse "," (map show [x circle, y circle, r circle])