在haskell中同时实现两个或多个实例

时间:2015-02-02 13:03:16

标签: haskell

我在Haskell中定义了以下类:

class SearchList searchEntity where
    searchList :: [ArtifactTree] -> searchEntity -> [Artifact] 

对于不同的实体,我有两个相同的类实现:

instance SearchList Version where
    searchList [] _ = []
    searchList (artifactTree:[]) element = searchElement artifactTree element
    searchList (x:xs) version = (searchElement x version) ++ (searchList xs version)
instance SearchList Artifact where
    searchList [] _ = []
    searchList (artifactTree:[]) element = searchElement artifactTree element
    searchList (x:xs) artifact = (searchElement x artifact) ++ (searchList xs artifact)

有没有办法将两个相等的实例合并为一个以避免代码重复?例如,我正在寻找类似于

的东西
instance SearchList {Version, Artifact} where
    searchList [] _ = []
    searchList (artifactTree:[]) element = searchElement artifactTree element
    searchList (x:xs) version = (searchElement x version) ++ (searchList xs version)

2 个答案:

答案 0 :(得分:2)

正如Reid Henrichs所说,一般情况下无法做到这一点,在这种情况下可能没有必要。但是,有一些事情可能会非常有用。

高级类型

不要被疯狂的名字吓跑。例如,Maybe类型是“更高级的”,因为您不能拥有Maybe类型的值 - 它需要为Maybe a类型a }。处理高级类型的类型类有两种方法。一种方法是实际上制作一个更高级的课程。另一个是制作多态实例。例如,您可以拥有

class Foo f where
  foom :: f a -> Int

instance Foo [] where
  foom lst = length lst

或者你可以

class Bar t where
  boom :: t -> Int

instance Bar [a] where
  boom lst = length lst

助手功能

假设您有一个类,并希望Int列表的实例和Bool列表以及[Bool]列表都以大致相同的方式行事,但其他类型的列表做其他事情。您可以编写实现该常见行为的列表函数,然后编写三个使用函数的小实例声明。

答案 1 :(得分:0)

此函数不需要类型类。一般来说,没有办法做你所要求的,但如果你的函数具有相同的实现,那么它们通常可以在没有类型类的情况下编写。