altern
altern

Reputation: 5949

Implement two or more instances simultaneously in haskell

I have defined following class in Haskell:

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

I have two equal implementations of this class for different entities:

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)

Is there a way to combine two equal instances into one to avoid code duplication? For example, I am looking for something similar to

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

Upvotes: 0

Views: 95

Answers (2)

dfeuer
dfeuer

Reputation: 48601

As Reid Henrichs said, there is no way to do this in general, and it's probably not necessary in this case. However, there are a couple things that can be very helpful.

Higher-kinded types

Don't get scared off by the crazy name. The Maybe type, for example, is "higher-kinded", because you can't have a value of type Maybe—it needs to have type Maybe a for some a. There are two ways to deal with type classes for higher-kinded types. One way is to actually make a higher-kinded class. Another is to make a polymorphic instance. So for example, you can have

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

instance Foo [] where
  foom lst = length lst

or you can have

class Bar t where
  boom :: t -> Int

instance Bar [a] where
  boom lst = length lst

Helper functions

Suppose you have a class, and want the instances for lists of Int and lists of Bool and lists of [Bool] to all act in about the same way, but other sorts of lists to do something else. You can write list functions implementing that common behavior, and then write three tiny little instance declarations that use the functions.

Upvotes: 2

Rein Henrichs
Rein Henrichs

Reputation: 15605

You do not need a typeclass for this function. There is no way to do what you are asking in general, but if your functions have identical implementations then they can often be written without a typeclass anwyway.

Upvotes: 0

Related Questions