在Haskell中定义一个任意递归类型的Show

时间:2011-12-16 22:37:29

标签: haskell typeclass

我正在尝试将自定义类型设为Show。

的实例

这是theType,它只是一个基本的Set类型。

data Set a = Insert a (Set a) | EmptySet

我想要像

这样的东西
Insert 1 (Insert 2 (Insert 3 EmptySet))

显示如

{1, 2, 3}

我该怎么做?我尝试使用字符串连接,但似乎做字符串插值被认为是不好的形式(Haskell似乎本身不支持这个?)另外,我如何得到列表周围的花括号?到目前为止,我所能做的就是这个,基本上什么都没做......

instance (Show a) => Show (Set a) where
     show EmptySet = ""
     show (Insert a as) = show a ++ show as 

此外,我尝试使用Hoogle和Hayoo查找List实现,以便我可以看到这是如何在列表中实现的。我找不到它。有人对此有任何指示吗?我试着搜索“show :: [a] - > String”,“Data.Lists”,“Lists”等....

3 个答案:

答案 0 :(得分:5)

你的这种类型仍然与列表同态。无论在何处定义Show实例;你仍然可以使用它:

toList (Insert a b) = a:toList b
toList EmptySet = []

instance Show a => Show (Set a) where
    show = show . toList

答案 1 :(得分:5)

这是一个直接递归的解决方案:

instance Show a => Show (Set a) where
  show = ('{' :) . go
    where
      go EmptySet            = "}"
      go (Insert x EmptySet) = show x ++ "}"
      go (Insert x xs)       = show x ++ ", " ++ go xs

如果您不喜欢(++)的低效使用,您当然可以使用difference lists

instance Show a => Show (Set a) where
  show = ('{' :) . ($ []) . go
    where
      go EmptySet            = ('}' :)
      go (Insert x EmptySet) = shows x . ('}' :)
      go (Insert x xs)       = shows x . (", " ++) . go xs

应该这样做;所以,让我们来测试一下:

> show (Insert 2 (Insert 3 (Insert 5 EmptySet)))
"{2, 3, 5}"

答案 2 :(得分:4)

数据类型可能是递归的,但这并不是函数递归的原因。

import Data.List (intercalate)

instance Show a => Show (Set a) where
  show x = "{" ++ intercalate ", " (toList x) ++ "}"

这假设您有一个函数toList :: Set a -> [a]。递归隐藏在那里。

List实现是通过Show typeclass中的showList函数完成的(因此String s,又名[Char],可以不同方式显示。