[Haskell] What is the best way to write adapters?

Ben_Yu at asc.aon.com Ben_Yu at asc.aon.com
Fri Mar 12 10:33:21 EST 2004





Well. The instance declaration is like this:
instance FwdSig Native
instance FwdSig Def
instance FwdSig d => Sig d
instance Sig XXX

Neither Native nor Def are direct instances of Sig.
And this XXX, it is an instance of Sig, not a FwdSig.

As you can see, there's no real overlapping at all if we take the "FwdSig d
=>" as a precondition for "Sig d".

However, ghc seems disregard the "FwdSig d =>" piece and insists that the
"Sig d" and "Sig XXX" forms an overlapping.

This confuses me and the only reason I can figure out is that ghc does not
attempt to resolve ambiguity based on "=>", which, I guess, could make the
implementation simpler.





Brandon Michael Moore <brandon at its.caltech.edu>@haskell.org on 03/11/2004
06:56:41 PM

Sent by:    haskell-bounces at haskell.org


To:    Ben_Yu at asc.aon.com
cc:    haskell at haskell.org, oleg at pobox.com

Subject:    Re: [Haskell] What is the best way to write adapters?



On Thu, 11 Mar 2004 Ben_Yu at asc.aon.com wrote:
>
> Thanks! Oleg.
>
> This works and it looks nice!
>
> And now, my code can be like:
>
> class FwdSig d where
>   (forall a. Sig a => a -> w) -> d -> w
>
> All the types that supports such forwarding are instances of FwdSig.
>
> My Def type is:
>
> instance FwdSig Def where
>   fwd f (ClassDef c) = f c
>   fwd f (ProtDef p) = f p
>
> instance Sig Def where
>   getName = fwd getName
>   getMethods = fwd getMethods
>   ...
>
> My Native type is:
>
> instance FwdSig Native where
>   fwd f (NativeSignature s) = f s
>   fwd f (NativeProtocol p) = f p
>
> instance Sig Native where
>   getName = fwd getName
>   getMethods = fwd getMethods
>   ...
>
> Many annoying forwarding functions are gone.
>
> The only thing that I hope to be better is this "getXXX = fwd getXXX"
piece
> of code. Is it possible to reuse the same piece of code for both Native
and
> Def and any other possible types?

I'm not as handy with the type system as Oleg, but I can help out here.

The problem with your new instance is that if the compiler is trying to
see if Native is an instance of Sig, it can start with the declaration Sig
Native, or the declarations FwdSig a => Sig a, both of which could
potentially derive an instance of Sig Native.

Additionally passing the -fallow-overlapping-instances flag will permit
you to compile a program where instances overlap like this, and will
select the most specific matching instance (looking only at the head).
Your code is fine.

Brandon

> Inspired by your generic code, I wrote such thing:
>
> instance FwdSig d => Sig d where
>   getName = fwd getName
>   getMethods = fwd getMethods
>   ...
>
> However, my ghc complains about the use of "Sig d".
>
> I followed its recommendation and put -fallow-undecidable-instances flag
> with the surprise that the "FwdSig d=>Sig d" instance declaration
conflicts
> with my other "instance Sig XXX" declarations.
>
> Surely this is not a serious problem, I can live with repeating the
> "getXXX=fwd getXXX" several times. Just curious about how further this
can
> go.
>
> Ben.


_______________________________________________
Haskell mailing list
Haskell at haskell.org
http://www.haskell.org/mailman/listinfo/haskell





This message is intended only for the addressee and may contain information
that is confidential or privileged. Unauthorized use is strictly prohibited
and may be unlawful. If you are not the intended recipient, or the person
responsible for delivering to the intended recipient, you should not read,
copy, disclose or otherwise use this message, except for the purpose of
delivery to the addressee. If you have received this email in error, please
delete and advise us immediately.



More information about the Haskell mailing list