Hi Brent,


Think about what (show . host $ a) does.  It takes 'a', converts it
to... any type which is an instance of IPHost, and then shows that,
turning it into a String.  But there can be multiple types which are
instances of IPHost, and each of them could have a *different* Show
instance.  So the exact String you get out depends on what type you
pick... but there's no way for Haskell to infer which type to use.
This is why it suggests to add a type signature.  But I think there is
probably some confusion that needs to be cleared up, the code you have
doesn't quite make sense.  Here are some questions to ask yourself:

 1. Do you really want to be able to have multiple instances for
    IPHost and IPMask?  (The answer might legitimately be 'yes', I'm
    just making sure.)  What sorts of types do you have in mind that
    will be instances of these classes?

Yes. Basically my goal was to have something like:

data IPv4Host = IPv4Host Word32
                deriving (Show)
instance IPHost IPv4Host where

data IPv4Mask = IPv4Mask Word32
                deriving (Show)
instance IPMask IPv4Mask where

data IPv4Addr = IPv4Addr IPv4Host IPv4Mask
instance IPAddr IPv4Addr where

and the equivalent for IPv6 (to be implemented later when I fugre out how to do it...)
 


 2. Do you really intend for the 'host' and 'mask' methods of the
    IPAddr class to be able to return *any* types which are instances
    of IPHost and IPMask, respectively? (This is what the code says
    right now.)  This is actually impossible given that IPHost and
    IPMask have no methods.  Or do you mean that for a given instance
    of IPAddr, the 'host' method (say) will return some *particular*
    type which happens to be an instance of IPHost, but which type is
    returned may differ between instances of IPAddr?  

Yes! That's exactly what I want (and yes there will be methods eventually in those classes)
 
If that's
    really what you mean, I would suggest either using a
    multi-parameter type class, like so:

      class (IPHost h, IPMask m) => IPAddr a h m where
        host :: a -> h
        mask :: a -> m

Ok... So I guess the instance declaration for IPv4Addr will then become this:

   instance IPAddr IPv4Addr IPv4Host IPv4Mask where

but how do I adjust the showIPAddr function to deal with that? I tried this:

   showIPAddr :: (IPAddr a h m) => a -> String

but something is still missing, I get:

    Could not deduce (IPAddr a b m) from the context (IPAddr a h1 m1)
      arising from a use of `host' at IP.hs:23:23-26
    Possible fix:
      add (IPAddr a b m) to the context of
        the type signature for `showIPAddr'
    In the second argument of `(.)', namely `host'
    In the first argument of `($)', namely `show . host'
    In the first argument of `(++)', namely `(show . host $ a)'


Thanks a lot,

Patrick

 


    OR using existential quantification to hide the particular types
    returned by 'host' and 'mask'.

-Brent
_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners



--
=====================
Patrick LeBoutillier
Rosemère, Québec, Canada