为自定义的NestedList类型实例化Show typeclass

时间:2019-04-14 23:15:06

标签: haskell

我已经定义了以下自定义类型的任意深层列表

data NestedList a
    = Elem a
    | List [NestedList a]

并且我想实例化Show并漂亮地打印我的嵌套列表,但是我对show函数应该如何查找我的类型一无所知

instance (Show a) => Show (NestedList a) where

例如,如果我们有

let a = List [List[Elem 2], Elem 1, List[Elem 1, Elem 2],
              List[List[Elem 2, Elem 3]], Elem 5]

我要show a打印

"[[2], 1, [1, 2], [[2, 3]], 5]"

如何实现show函数?

2 个答案:

答案 0 :(得分:4)

我相信这是您想要的实例:

data NestedList a = Elem a | List [NestedList a]

instance (Show a) => Show (NestedList a) where
    show (Elem a) = show a
    show (List xs) = "[" ++ intercalate ", " (map show xs) ++ "]"

请注意,您需要从intercalate导入Data.List。 (这与我在评论中提到的intersperse不同-抱歉,我匆忙选择了一个错误的词。)

我希望您一看便有道理-我们只需为show借用a实例来处理Elem a情况。然后List案例显示所有元素,将字符串", "放在每个元素之间,并将整个元素括在方括号中。

可以在您的示例中使用的证据:

Prelude Data.List> :{
Prelude Data.List| let a = List [List[Elem 2], Elem 1, List[Elem 1, Elem 2],
Prelude Data.List|               List[List[Elem 2, Elem 3]], Elem 5]
Prelude Data.List| :}
Prelude Data.List> a
[[2], 1, [1, 2], [[2, 3]], 5]

答案 1 :(得分:0)

您不必实现Show,只需要求编译器派生它即可:

data NestedList a = Elem a | List [NestedList a]
deriving Show

Show类型类通常保留用于以一种可以被语言读取的格式打印值。

  

Show的派生实例具有以下属性,这些属性与Text.Read.Read的派生实例兼容:* show的结果是语法正确的Haskell表达式,其中仅包含常量,并给出了固定性声明。类型被声明。它仅包含在数据类型,括号和空格中定义的构造函数名称。使用带标签的构造函数字段时,还使用大括号,逗号,字段名称和等号。

按照惯例,您的函数应与Show typeclass实例分开定义。