我有data RegEx
,我想实施instance Show a => Show RegEx a
。这是我的代码:
showAtom :: Show a => RegEx a -> String
showAtom (Lit x) = show x
showAtom r = "(" ++ (show r) ++ ")"
instance Show a => Show (RegEx a) where
show (Lit x) = show [x]
show (Opt r) = (showAtom r) ++ "?"
show (Alt p q) = (showAtom p) ++ "|" ++ (showAtom q)
show (Seq p q) = (show p) ++ (show q)
show (Rep r) = (showAtom r) ++ "*"
showAtom
函数只是一个实现细节。有没有办法让我隐藏它,这样只有instance
定义才能看到它?或者更好的是,只在show
内显示它。
答案 0 :(得分:6)
这样的事情应该有效:
instance Show a => Show (RegEx a) where
show x = show' x
where
showAtom :: Show a => RegEx a -> String
showAtom (Lit x) = show x
showAtom r = "(" ++ (show r) ++ ")"
show' (Lit x) = show [x]
show' (Opt r) = (showAtom r) ++ "?"
show' (Alt p q) = (showAtom p) ++ "|" ++ (showAtom q)
show' (Seq p q) = (show p) ++ (show q)
show' (Rep r) = (showAtom r) ++ "*"
或者,您可以从模块的导出列表中排除showAtom
。
答案 1 :(得分:2)
只是不要在模块export list中列出showAtom
。
答案 2 :(得分:1)
您可以通过不导出模块使showAtom
本地化,但这仍然会使其在整个模块中可见 - 而不仅仅是实例或show
函数。
要使其成为show
函数的本地函数,您需要使用let
或where
,但在函数参数中使用模式匹配时,这些都不适用于多种情况名单。您可以通过将模式匹配移动到case
语句中来使其工作:
instance Show a => Show (RegEx a) where
show re =
let
showAtom :: Show a => RegEx a -> String
showAtom (Lit x) = show x
showAtom r = "(" ++ (show r) ++ ")"
in
case re of
(Lit x) -> show [x]
(Opt r) -> (showAtom r) ++ "?"
(Alt p q) -> (showAtom p) ++ "|" ++ (showAtom q)
(Seq p q) -> (show p) ++ (show q)
(Rep r) -> (showAtom r) ++ "*"