martingw
martingw

Reputation: 4233

Haskell: Instance for data multiple type variables?

I want to create a type class for various types of "columns of stuff", so something like this:

class Column c where
     at :: c a -> Int -> a

data ListColumn a = ListColumn {
     lcContent :: [a]
}

instance Column ListColumn where
  at c i = lcContent c !! i

Now I want to derive one column from another. Say I have a column of customers, and I want to derive a column of customer names from that. So I wrote:

data DerivedColumn a b c = DerivedColumn {
    dcBase   :: c a, 
    dcDerive :: a -> b
}

a being the customer, b the customer name in the example above. Now I thought I could write something like this:

instance Column (DerivedColumn a b) where
    at c i = dcDerive c $ at (dcBase c) i

But ghc does not seem to like it (Column should have kind * -> *, but DerivedColumn a b has kind (* -> *) -> *). Can someone please point in the right direction...?

Upvotes: 1

Views: 796

Answers (1)

Emil
Emil

Reputation: 2167

I think what you want instead is this:

data DerivedColumn c a b = DerivedColumn {
    dcBase   :: c a, 
    dcDerive :: a -> b
}

instance Column c => Column (DerivedColumn c a) where
    at dc i = dcDerive $ at (dcBase dc) i

To expand a bit, if you look at your Column class, you'll see that c has kind * -> *, and the a in c a is the type of the values that c contains. I assume that the value of the columns that DerivedColumn a b c contains should have type b, so it should really be the last value you pass to the type constructor for you to define an instance of Column.

Upvotes: 2

Related Questions