[Haskell-cafe] Am I using type families well?
Yves Parès
limestrael at gmail.com
Tue Nov 2 03:32:52 EDT 2010
I understand your point Ryan, but in that case, why didn't the error occur
when Resource and ResourceId were separated classes?
BTW, I assume for your Int instance of Resource, you meant:
> instance Resource Int where
> type IdOf *Int* = Int
> type LocOf *Int* = String
> type CfgOf *Int* = ()
> retrieveLoc () n = "Int_ " ++ show n
> load = undefined
> unload = undefined
2010/11/2 Ryan Ingram <ryani.spam at gmail.com>
> This one is easy:
>
> > -- | Class describing a resource of type @rsc@
> > class (Ord (IdOf rsc)) => Resource rsc where
> > type IdOf rsc
> > type LocOf rsc
> > type CfgOf rsc
> > retrieveLoc :: CfgOf rsc -> IdOf rsc -> LocOf rsc
> > load :: LocOf rsc -> IO (Maybe rsc)
> > -- ^ Called when a resource needs to be loaded
> > unload :: rsc -> IO ()
> > -- ^ Idem for unloading
>
> Consider this:
>
> instance Resource () where
> type IdOf () = Int
> type LocOf () = String
> type CfgOf () = ()
> retrieveLoc () n = "Unit_" ++ show n
> load = undefined
> unload = undefined
>
> instance Resource Int where
> type IdOf () = Int
> type LocOf () = String
> type CfgOf () = ()
> retrieveLoc () n = "Int_ " ++ show n
> load = undefined
> unload = undefined
>
> foo = retrieveLoc :: () -> Int -> String -- which retrieveLoc is called
> here?
>
> The problem, in case you haven't surmised it, is that retrieveLoc is
> ambiguous; you can never call it! There's no way to know which
> instance you might be referring to. You can work around it by making
> one of the type families into a data family (which is injective; you
> know that if CfgOf x = CfgOf y, then x = y). Or you can add a proxy
> parameter to retrieveLoc:
>
> > data Proxy a = Proxy
> > retrieveLoc :: Proxy rsc -> CfgOf rsc -> IdOf rsc -> LocOf rsc
>
> now:
>
> > foo = retrieveLoc (Proxy :: Proxy ())
>
> and ghc can correctly infer foo's type as
> > foo :: () -> Int -> String
>
> and foo will call the retrieveLoc from the () instance.
>
> -- ryan
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/haskell-cafe/attachments/20101102/7adf897c/attachment.html
More information about the Haskell-Cafe
mailing list