我正在尝试实现数据类型的show方法.
data OptionList a b = EmptyOpt | OptionList { optListHead :: a, optListTail :: b } deriving (Read) instance (Show a, Show b) => Show (OptionList a b) where show (OptionList a EmptyOpt) = "{" ++ (show a) ++"}" show (OptionList EmptyOpt b) = "{" ++ (show b) ++"}" show (OptionList a b) = "{"++ (show a) ++ ", " ++ (show b) ++"}" show EmptyOpt = ""
我希望OptionList不显示逗号,如果其中一个a
或b
具有由EmptyOpt构造的值.但编译器显示以下错误:
OptionList.hs:11:28: Couldn't match expected type ‘b’ with actual type ‘OptionList t0 t1’ ‘b’ is a rigid type variable bound by the instance declaration at OptionList.hs:10:10 Relevant bindings include show :: OptionList a b -> String (bound at OptionList.hs:11:9) In the pattern: EmptyOpt In the pattern: OptionList a EmptyOpt In an equation for ‘show’: show (OptionList a EmptyOpt) = "{" ++ (show a) ++ "}" OptionList.hs:12:26: Couldn't match expected type ‘a’ with actual type ‘OptionList t2 t3’ ‘a’ is a rigid type variable bound by the instance declaration at OptionList.hs:10:10 Relevant bindings include show :: OptionList a b -> String (bound at OptionList.hs:11:9) In the pattern: EmptyOpt In the pattern: OptionList EmptyOpt b In an equation for ‘show’: show (OptionList EmptyOpt b) = "{" ++ (show b) ++ "}"
更新:OptionList应该是类似无类型列表的东西.
(+:) :: a -> b -> (OptionList a b) infixr 5 +: t1 +: t2 = OptionList t1 t2
所以,像这样的列表0 +: "test" +: True
将被定义为OptionList Int (OptionList String (OptionList Bool EmptyOpt))
和将被定义show
为{0, {"test", {True}}}
更新的更新.如果您愿意打开某些扩展程序,可以使其正常工作:
{-# LANGUAGE FlexibleInstances #-} data EmptyOpt = EmptyOpt data OptionList a b = OptionList a b deriving (Read) instance (Show a, Show b) => Show (OptionList a b) where show (OptionList a b) = "{ " ++ show a ++ ", " ++ show b ++ " }" instance {-# OVERLAPPING #-} (Show a) => Show (OptionList a EmptyOpt) where show (OptionList a EmptyOpt) = "{ " ++ show a ++ " }" (+:) :: a -> b -> (OptionList a b) infixr 5 +: t1 +: t2 = OptionList t1 t2 test = 0 +: "test" +: True +: EmptyOpt
但我个人会尝试用类似的东西
data Option = B Bool | I Int | S String data OptionsList = Empty | OptionsList Option OptionsList
你的麻烦是,例如,头((Show a, Show b) => Show (OptionList a b)
)说,要实现Show
对OptionList a b
地方a
和b
任何类型的Show
实例,但在你执行你要求这两个a
和b
实际上都是类型OptionList
.
也许您会将类型更改为更像普通列表:
data OptionList a = EmptyOpt | OptionList { optListHead :: a , optListTail :: OptionList a} deriving (Read)
然后你可以有一个实例:
instance (Show a) => Show (OptionList a) where show (OptionList a EmptyOpt) = "{" ++ show a ++"}" show (OptionList a b) = "{"++ show a ++ ", " ++ show b ++"}" show EmptyOpt = ""