我正在尝试将自定义类型设为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”等....
答案 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]
,可以不同方式显示。