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



Reply via email to