
Thomas M. DuBuisson wrote:
The solution I would want looks like this:
class NetworkAddress a where addressByteSize :: a -> Int
instance (NetworkAddress a) => Binary (AddressBlock a) where get = do lenH <- get h <- replicateM get (fromIntegral lenH) lenT <- get t <- replicateM get (fromIntegral lenT) nr <- get let addrSize = addressByteSize (undefined :: a) bytes = (addrSize - lenH - lenT) * nr addrs <- replicateM get (fromIntegral bytes) return ...
The following works in Haskell 98: get = let result = do lenH <- get h <- replicateM get (fromIntegral lenH) lenT <- get t <- replicateM get (fromIntegral lenT) nr <- get let addrSize = addressByteSize (getAddressType result) bytes = (addrSize - lenH - lenT) * nr addrs <- replicateM get (fromIntegral bytes) return ... getAddressType :: Get (AddressBlock a) -> a getAddressType _ = undefined in result The trick is to use an auxillary function (getAddressType) to extract a value of the desired type from the result type of get. This is one of the few places where the monomorphism actually helps; without it, 'result' would get a polymorphic type and the right instance of NetworkAddress would remain undetermined. There's probably a solution using pattern signatures [1] but I couldn't get it to work in my first attempt. I didn't try scoped type variables [2]. [1] http://tinyurl.com/2533oc (http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html...) [2] http://tinyurl.com/2ypmvx (http://www.haskell.org/ghc/docs/latest/html/users_guide/type-extensions.html...) HTH, Bertram