实现`instance`时如何隐藏辅助函数

时间:2013-04-27 21:07:53

标签: haskell

我有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内显示它。

3 个答案:

答案 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函数的本地函数,您需要使用letwhere,但在函数参数中使用模式匹配时,这些都不适用于多种情况名单。您可以通过将模式匹配移动到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) ++ "*"