I'm not sure if this can be cleanly done or not. (I've been able to do
it less-than-cleanly.) What I want to do is define a class where the
instance has an option of what type of parameters some of its functions
can accept. For example, say I have
class Foo a where
write :: a -> b -> IO ()
This allows a particular instance's version of `write' to accept any
type of value as the second parameter. However some instances may not be
able to accept _any_ type of parameter; maybe some can only write
Strings. I have been able to accomplish what I want by using a bit of a
kludge:
data MaybePoly b = IsPoly b | NotPoly String
class FooKludge a where
write :: a -> MaybePoly b -> IO ()
instance FooKludge OnlyStrings where
write only (NotPoly str) = send str
write _ (IsPoly _) = ioError $ userError "I can't accept this."
The problem is that every function call to `write' has to package up the
variable into a MaybePoly, which gets rather ugly. If I have a function
that returns a MaybePoly, then it has to be unpackaged as well. Can
anyone think of a "prettier" way?
It wouldn't be so bad if I could even do as much as:
polyX :: MaybePoly a -> a
polyX (IsPoly x) = x
polyX (NotPoly str) = str
But that fails to type-check.
Thanks for all input,
Michael Hobbs