4

我有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.

4

3 回答 3

7

像这样的东西应该工作:

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从模块的导出列表中排除。

于 2013-04-27T21:17:22.130 回答
2

只是不要showAtom在模块的导出列表中列出

于 2013-04-27T21:16:41.130 回答
1

您可以showAtom通过不导出模块来使其成为本地模块,但这仍然会使其在整个模块中可见 - 而不仅仅是实例或show函数。

要使其对show函数本地化,您需要使用letor 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) ++ "*"
于 2013-04-27T21:21:37.420 回答