[Haskell-cafe] What's wrong with the classes/insances?
Pieter Laeremans
pieter at laeremans.org
Fri Jun 20 18:44:13 EDT 2008
Thanks all!
I have to admit, I have an OO mndset :-).
I think I have found a more "functional design" :
import Text.StringTemplate.Classes
import Text.StringTemplate
data (ToSElem a) => Item a b = Item {cargo::a , catalog :: (Catalog a b)}
instance (ToSElem a) => ToSElem (Item a b) where
toSElem = (toSElem . cargo)
type Id = String
type ItemToSelem a b = Item a b -> SElem b
type ItemParser a b = String -> Item a b
type AllItemReader a b = IO [Item a b]
type SingleItemReader a b = Id -> IO (Item a b)
data Catalog a b = Catalog {reader:: (AllItemReader a b),
singleReader ::( SingleItemReader a b)}
data Content = Content {authort :: String, text:: String}
type ContentItem = Item Content String
What I want to express is that there exists differnet kinds of catalogs which,
depending on how they are configured can read from a file system or a database.
And each catalog can contain a specific type of Item.
For each Item I have to be able to produce the toSELem representation
that subsequently can be used by HStringTemplate
I thik that means I could declare
On Sat, Jun 21, 2008 at 12:26 AM, Dan Doel <dan.doel at gmail.com> wrote:
> 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
>
--
Pieter Laeremans <pieter at laeremans.org>
"The future is here. It's just not evenly distributed yet." W. Gibson
More information about the Haskell-Cafe
mailing list