[Haskell-cafe] Improving MPTC usability when fundeps aren't
appropriate?
Bertram Felgenhauer
bertram.felgenhauer at googlemail.com
Thu Aug 13 18:32:05 EDT 2009
Daniel Peebles wrote:
> I've been playing with multiparameter typeclasses recently and have
> written a few "uncallable methods" in the process. For example, in
>
> class Moo a b where
> moo :: a -> a
>
> Another solution would be to artificially force moo to take
> a "dummy" b so that the compiler can figure out which instance you
> meant. That's what I've been doing in the mean time, but wouldn't it
> be simpler and less hackish to add a some form of "instance
> annotation", like a type annotation, that would make it possible to
> specify what instance you wanted when it's ambiguous?
Syntax aside, dummy arguments have a disadvantage when it comes to
optimizing code, because the compiler doesn't know that the dummy
argument is unused in the function; indeed you could define instances
where the dummy argument is used.
For this reason it's technically better to use a newtype instead:
newtype Lambda t a = Lambda { unLambda :: a }
and, say,
class Moo a b where
moo :: Lambda b (a -> a)
Note that we can convert between functions taking dummy arguments and
such "lambda" types easily:
lambdaToDummy :: Lambda t a -> t -> a
lambdaToDummy a _ = unLambda a
dummyToLambda :: (t -> a) -> Lambda t a
dummyToLambda f = Lambda (f undefined)
In fact, lambdaToDummy makes a great infix operator:
(@@) :: Lambda t a -> t -> a
(@@) = lambdaToDummy
infixl 1 @@
Now we can write
moo @@ (undefined :: x)
where with dummy arguments we would write
moo (undefined :: x) .
The compiler will inline (@@) and lambdaToDummy (they're both small)
and produce
unLambda moo ,
that is, the plain value of type a -> a that we wanted to use in the
first place. All this happens after type checking and fixing the
instance of Moo to use.
Bertram
More information about the Haskell-Cafe
mailing list