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

Implement two or more instances simultaneously in haskell

我在 Haskell 中定义了以下 class:

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

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

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)

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

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

高等类型

不要被这个疯狂的名字吓跑了。例如,Maybe 类型是“higher-kinded”,因为您不能拥有类型 Maybe 的值——对于某些 a,它需要具有类型 Maybe a ].有两种方法可以处理更高类型的类型 classes。一种方法是实际制作一个更高级的 class。另一个是制作多态实例。例如,您可以

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

辅助函数

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