Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
重构Haskell代码_Haskell_Refactoring_Dry_Typeclass - Fatal编程技术网

重构Haskell代码

重构Haskell代码,haskell,refactoring,dry,typeclass,Haskell,Refactoring,Dry,Typeclass,实例化一个typeclass可以通用化吗 我有以下几点Haskell代码: data Variable = Var Char (Maybe Integer) deriving (Eq) instance Show Variable where show (Var c Nothing) = [c] show (Var c (Just n)) = c : show n data Funcsymb = FuncS Char (Maybe Integer) derivi

实例化一个typeclass可以通用化吗

我有以下几点Haskell代码:

data Variable = Var Char (Maybe Integer)
    deriving (Eq)
instance Show Variable where
    show (Var c Nothing) = [c]
    show (Var c (Just n)) = c : show n

data Funcsymb = FuncS Char (Maybe Integer)
    deriving (Eq)
instance Show Funcsymb where
    show (FuncS c Nothing) = [c]
    show (FuncS c (Just n)) = c : show n

data Relsymb = RelS Char (Maybe Integer)
    deriving (Eq)
instance Show Relsymb where
    show (RelS c Nothing) = [c]
    show (RelS c (Just n)) = c : show n

我能不重复地写吗?我知道我可以使用
(Char,可能是Integer)
来处理这三种类型,但我更希望使用单独的类型。

您可以使用make-helper函数来减少重复

showIfJust :: (Show a) => Maybe a -> String
showIfJust (Just a) = show a
showIfJust _ = ""

showCharMaybe = (Show a) => Char -> Maybe a -> String
showCharMaybe c m = c : showIfJust m

data Variable = Var Char (Maybe Integer)
    deriving (Eq)

instance Show Variable where
    -- this can be written as
    -- c : showIfJust n
    -- or showCharMaybe c m
    show (Var c mn) = showCharMaybe c mn

data Funcsymb = FuncS Char (Maybe Integer)
    deriving (Eq)

instance Show Funcsymb where
    show (FuncS c mn) = showCharMaybe c mn

data Relsymb = RelS Char (Maybe Integer)
    deriving (Eq)

instance Show Relsymb where
    show (RelS c mn) = showCharMaybe c mn

此外,您还可以将
数据
声明切换为
newtype
,因为它们都是单构造函数声明。这是一个小优化

您可以使用make-helper函数来减少重复

showIfJust :: (Show a) => Maybe a -> String
showIfJust (Just a) = show a
showIfJust _ = ""

showCharMaybe = (Show a) => Char -> Maybe a -> String
showCharMaybe c m = c : showIfJust m

data Variable = Var Char (Maybe Integer)
    deriving (Eq)

instance Show Variable where
    -- this can be written as
    -- c : showIfJust n
    -- or showCharMaybe c m
    show (Var c mn) = showCharMaybe c mn

data Funcsymb = FuncS Char (Maybe Integer)
    deriving (Eq)

instance Show Funcsymb where
    show (FuncS c mn) = showCharMaybe c mn

data Relsymb = RelS Char (Maybe Integer)
    deriving (Eq)

instance Show Relsymb where
    show (RelS c mn) = showCharMaybe c mn

此外,您还可以将
数据
声明切换为
newtype
,因为它们都是单构造函数声明。这是一个小优化

如果您喜欢单独的类型,为什么不使用
newtype
?您可以定义“showSym::Char->Maybe Integer->String”。另外,您可能需要弄清楚文本输出中的类型。@Zeta我不确定
newtype
在这里有什么帮助。我仍然需要编写三个独立的
实例
s,对吗?@Veky是的,但这些都很简单,比如
show(MyWrapper a)=show a
(当然你也可以在这里这么做)-如果你不需要覆盖任何其他内容,那么简单的类型同义词就可以了。。。所以我定义了另一个(基本)类型,为它编写show,然后使用它定义这三个?或者你是说我可以说
实例Show(Char,可能是Integer)where…
而不定义新类型?如果你喜欢单独的类型,为什么不使用
newtype
?你可以定义“showSym::Char->可能是Integer->String”。另外,您可能需要弄清楚文本输出中的类型。@Zeta我不确定
newtype
在这里有什么帮助。我仍然需要编写三个独立的
实例
s,对吗?@Veky是的,但这些都很简单,比如
show(MyWrapper a)=show a
(当然你也可以在这里这么做)-如果你不需要覆盖任何其他内容,那么简单的类型同义词就可以了。。。所以我定义了另一个(基本)类型,为它编写show,然后使用它定义这三个?或者你是说我可以说
实例显示(Char,可能是整数)在哪里…
而不定义新类型?