你好,我是Haskell的新手,我想知道:
对于每个新定义的类型构造函数,即使它是深度为 0 的东西,例如:
data Letter =A | B | C deriving (Show)
我必须提供吗
instance Show Type
Letter A = "A"
Letter B ="B"
Letter C ="C"
我知道对于嵌套类型,您必须提供Show
实现,但是对于简单的东西,没有其他方法可以使用与反射(C#(等效的东西吗?只需获取属性名称/构造函数名称并ToString
-it?
Haskell程序员是否为他们创建的任何临时类型提供Show
实例?
通过嵌套类型,我的意思是将一个简单的 ADT 放在另一个 ADT 中,等等。但你想要的只是得到他们的名字:
例如:
data Person = Male | Female
data IsMarried=Yes | No
data Worker=Worker{
person::Person,
status::IsMarried
}
对于这种嵌套,我真的必须为所有这些类型构造函数定义instance
Show
,即使我想要的只是将它们的名称"字符串化"?
我是否必须为每种类型提供一个 show 实例?
否,因为您已自动派生Show
:
data Letter = A | B | C deriving (Show)
-- ^^^^^^^^^^^^^^^ Here
但是,如果您想要一个"更智能"的show
,例如将自定义列表显示为[1,2,3]
而不是一堆构造函数,您将不得不自己编写。
你可以对许多类(包括Eq
、Ord
、Read
、Enum
和Bounded
(做同样的事情,但大多数类,包括用户定义的类,必须在不使用某些语言扩展的情况下手动实现。
我知道对于嵌套类型,您必须提供显示实现[...]
你没有!例如,我可以这样写:
data Maybe a = Just a | Nothing deriving (Show)
编译器将自动添加必要的约束,尽管它是"嵌套"类型。
只需获取属性名称/构造函数名称和ToString-it ?
Haskell中没有"属性" - 不要在这里考虑C#。show
相当于ToString
。 但是,TypeReps 中提供了一种类型反射形式,尽管我建议在你牢牢掌握 Haskell 之前不要使用它。
因为我更改答案时@AJFarmar编辑他的答案:
我是否必须提供 [每种类型的显示实例?
是的。通过使用deriving Show
派生它,或者通过提供类型实例
instance Show -type- where...
我知道对于嵌套类型,您必须提供显示实现[...]
是的,编译器不会为 Show 添加任何必要的实例。
data Test = Test -- no instance for Show
test :: String
test = show $ (Just Test :: Maybe Test)
不会编译并显示错误消息:
main.hs:4:8: error:
• No instance for (Show Test) arising from a use of ‘show’
• In the expression: show $ (Just Test :: Maybe Test)
In an equation for ‘test’: test = show $ (Just Test :: Maybe Test)
这就是为什么您还需要一个用于a
的Show
实例。但是,如果已经存在一个,则不必提供新的。