[Haskell-cafe] Type Family Relations
Matt Morrow
mjm2002 at gmail.com
Mon Jan 5 02:23:10 EST 2009
Hi,
> I think that
> >>> class HeaderOf addr hdr | addr -> hdr
> does not enforce that there must be a corresponding instance
> AddressOf hdr addr. Hence, the type checker cannot use that information
> either. Do you have a way to remedy that?
I've often wanted something similar, and experimenting with this
the following two options seem to be equivalent and work as desired:
-----------------------------------------------------------------------------
-- both options share this code:
-- | The crucial assertion
ipv4 :: AddrHdrPair IPv4 IPv4Header
ipv4 = AddrHdrPair
data IPv4Header = C1
data IPv4 = C2
data AppAddress = C3
data AppHeader = C4
-----------------------------------------------------------------------------
-- OPTION(1):
-- type families + GADT with equality constraints
type family HeaderOf addr
type family AddressOf hdr
data AddrHdrPair hdr addr
where AddrHdrPair :: (hdr ~ HeaderOf addr
,addr ~ AddressOf hdr) => AddrHdrPair addr hdr
type instance HeaderOf IPv4 = IPv4Header
type instance AddressOf IPv4Header = IPv4
-----------------------------------------------------------------------------
-- OPTION(2):
-- classes + GADT with instance constraints
class HeaderOf addr hdr | addr -> hdr
class AddressOf hdr addr | addr -> hdr
data AddrHdrPair hdr addr
where AddrHdrPair :: (HeaderOf addr hdr
,AddressOf hdr addr) => AddrHdrPair addr hdr
instance AddressOf IPv4Header IPv4
instance HeaderOf IPv4 IPv4Header
-----------------------------------------------------------------------------
-- And commenting out the above instances in turn
-- to verify that everything indeed works, and to
-- compare error message content:
{-
-- type instance HeaderOf IPv4 = IPv4Header
Cafe0.hs:9:0:
Couldn't match expected type `HeaderOf IPv4'
against inferred type `IPv4Header'
When generalising the type(s) for `ipv4'
Failed, modules loaded: none.
-- type instance AddressOf IPv4Header = IPv4
Cafe0.hs:9:0:
Couldn't match expected type `AddressOf IPv4Header'
against inferred type `IPv4'
When generalising the type(s) for `ipv4'
Failed, modules loaded: none.
-}
{-
-- instance AddressOf IPv4Header IPv4
Cafe0.hs:9:7:
No instance for (AddressOf IPv4Header IPv4)
arising from a use of `AddrHdrPair' at Cafe0.hs:9:7-17
Possible fix:
add an instance declaration for (AddressOf IPv4Header IPv4)
In the expression: AddrHdrPair
In the definition of `ipv4': ipv4 = AddrHdrPair
Failed, modules loaded: none.
-- instance HeaderOf IPv4 IPv4Header
Cafe0.hs:9:7:
No instance for (HeaderOf IPv4 IPv4Header)
arising from a use of `AddrHdrPair' at Cafe0.hs:9:7-17
Possible fix:
add an instance declaration for (HeaderOf IPv4 IPv4Header)
In the expression: AddrHdrPair
In the definition of `ipv4': ipv4 = AddrHdrPair
Failed, modules loaded: none.
-}
-- endcode
-----------------------------------------------------------------------------
I'm not sure if there are any circumstances under
which these two don't behave equivalently.
All the best,
Matt
More information about the Haskell-Cafe
mailing list