
Ahh, I see what you need, you want to "lift" the IArray functions into your type. Well, Rather than trying to instance the type- you could define your type like this: newtype Board = Board IArray.IArray ... whatever (!) :: Board -> Location -> Int (!) = IArray.(!) That is, create synonyms manually for each function you _absolutely need, assuming they don't conflict elsewhere. You would have to manually import each -- I feel like there is probably a better way to do this, but this will definitely work. Though, I'm not sure why you'd need to be instancing another class with a type like this, it's a _very_ specific type, I imagine one or the other set of functions ought to be easy enough to define simply about the type (dodging the typeclass entirely). I imagine extensibility comes to play here. One thing you might be able to do is class IArray a Location Int , OtherClass a ... => MyClass a ... where Which would force you to have a type which is an IArray of Location -> Ints, and an OtherClass, etc. I don't know all the details of your implementation, so I don't know how well this would work, but I imagine thats probably the "better" solution I'm thinking of... /Joe On Oct 31, 2009, at 11:42 PM, Shawn Willden wrote:
On Saturday 31 October 2009 08:55:56 pm Joe Fredette wrote:
Well, I think the issue is you're thinking too OOPy...
I understand what you're saying, but I don't think I am.
But let me answer the actual problem first, type classes are (basically) functions on types. So a type of "kind" `* -> * -> *` means it is a type which accepts two type variables. So:
newtype Foo a b = Foo (a, b)
Okay, that makes sense. What I'd read about kinds was considerably less clear. Thanks.
newtype Board = Board IArray ...
means that _you can just use the IArray types_! Well, almost, really what you want is a type-synonym:
type Board = IArray Location ...
Now you can write functions like
foo :: Board -> Int foo = Board !! (1,2)
and it will "just work" because Board _is_ an "IArray".
Hope that makes sense...
It does make sense, but it doesn't solve my problem. See, Board isn't the only type I have (and, also, Board has to be a newtype rather than a type synonym because it's also an instance of another class -- well, unless I want to turn on the extension that allows instances of synonyms, and I'm not sure what the etiquette is there), and some of the others aren't just IArrays with an aliased name, they have other data elements as well. For example:
data ScoredBoard = ScoredBoard { arry :: (IArray Location String) score :: Int maxScore :: Int }
I would like to be able to use (!), (//), bound, range, etc., on those as well, and without having to say "range (arry sb)", or having to define a bunch of fooRange, barRange, bazRange, etc., functions.
Basically I want to take this set of common array operations and overload them for a bunch of different types. As I understand it, classes are effectively the only way to overload in Haskell.
Perhaps it just isn't possible to do what I want? If kind signatures must match, then that's a problem, because different types will have different numbers of construction parameters.
Thanks for the help,
Shawn.