[Haskell-cafe] What's wrong with the classes/insances?
Dan Doel
dan.doel at gmail.com
Fri Jun 20 18:26:32 EDT 2008
On Friday 20 June 2008, Pieter Laeremans wrote:
> type Id = String
>
> class Catalog a where
> listItems :: a -> IO [String]
> getItem :: a -> Id -> IO (Maybe String)
>
> class Item a where
> getCatalog :: Catalog catalog => a -> catalog
>
> data Catalog c => Content c = Content {auteur :: String, inhoud::
> String, catalog::c}
>
> instance Catalog c => Item (Content c) where
> getCatalog (Content _ _ c) = c
>
> I get this as error from ghci:
>
> Couldn't match expected type `catalog' against inferred type `c'
> `catalog' is a rigid type variable bound by
> the type signature for `getCatalog'
> at
> ../Sites/liberaleswebsite/www.liberales.be/cgi-bin/Test.hs:16:26
> `c' is a rigid type variable bound by
> the instance declaration
> at
> ../Sites/liberaleswebsite/www.liberales.be/cgi-bin/Test.hs:20:17 In the
> expression: c
> In the definition of `getCatalog': getCatalog (Content _ _ c) = c
> In the definition for method `getCatalog'
> Failed, modules loaded: none.
The problem is in the type of getCatalog:
(Item a, Catalog catalog) => a -> catalog
That type says that given the a, you can produce a value of any type 'catalog'
so long as that type is an instance of Catalog.
What you probably meant it to say is that you can produce *some particular*
type that belongs to catalog. There are a couple ways you could express this.
For instance, using functional dependencies:
class Catalog cat => HasCatalog a cat | a -> cat where
getCatalog :: a -> cat
or the new type families:
class (Catalog (Cat a)) => Item a where
type Cat a :: *
getCatalog :: a -> Cat a
Or you could wrap catalogues in an existential type:
data SomeCatalog = forall c. Catalog c => Cat c
class Item a where
getCatalog :: a -> SomeCatalog
However, as just a word of warning, I'd say that when you run into something
like this, it's probably an indication that you're structuring your program
from an object oriented mindset, and that may not be the best fit for
programming in Haskell (of course, it's possible an existential type or some
such is the appropriate way to do things).
Cheers,
-- Dan
More information about the Haskell-Cafe
mailing list