Reputation: 4233
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
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