我正在尝试实现一种数据类型的 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 = ""
如果 a
或 b
之一具有由 EmptyOpt 构造的值,我希望 OptionList 不显示逗号。但是编译器显示如下错误:
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
n as {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 ba
和 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 = ""
关于haskell - 实例实现的模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41770707/