[Hs-Generics] xml deserialization using generics?

Hugh Perkins hughperkins at gmail.com
Sat Jun 30 13:17:03 EDT 2007


Oleg,

Ok that looks like exactly what I'm looking for :-)

Unfortunately I cant seem to run it.  It comes up with strange typing
messages when compiling:

*TestDeserialize> serialize P

<interactive>:1:0:
    No instance for (LDat (TL_red [a])
                          (HCons (Int -> [String])
                                 (HCons (Float -> [String]) (HCons (String
-> [S
tring]) HNil)))
                          (String -> String -> Person)
                          df)
      arising from use of `serialize' at <interactive>:1:0-10
    Possible fix:
      add an instance declaration for
      (LDat (TL_red [a])
            (HCons (Int -> [String])
                   (HCons (Float -> [String]) (HCons (String -> [String])
HNil))
)
            (String -> String -> Person)
            df)
    In the expression: serialize P
    In the definition of `it': it = serialize P

where P is:

getP = P "Lammel" "Amsterdam"

(for simplicity)

Similar looking errors with genCom, and/or with deserialize.

I guess I need to add an instance or deriving statement to the P class?

On another track, read through SYB3 a little, and it seems to have a really
clean way to create polymorphic functions, such as:

class Data a => StringParser a where
   parsestring :: String -> a
   parsestring x = fst $ head $gread(x)
instance StringParser Int where
   parsestring x = read x
instance StringParser String where
   parsestring x = read( "\"" ++ x ++ "\"" )

Looks like it should do exactly what I need: take a string and create any
data type, as long as the data type is an instance of Data.

Unfortunately, and strangely(?), it only seems to work for datatypes
declared as instance.  That's surprising since the default function in the
class declaration works for the Data class.  It would make sense if the
default function would be applied to all data types which are instances of
the base classes?

So, that didnt work yet.


A normal "read" ought to work, but there's no way of declaring that the
children of the parent data type are instances of Read, so it works straight
away less well (gets caught by the compiler).


The only return functions which build so far are:
      return  (fromJust $ fst $ head $ gread( "(" ++ (fromJust value) ++ ")"
) )
and:
      return ((fromJust . cast) value)

... but neither of these work particularly well at runtime, and they're
difficult to customize for different data types.


I really like the SYB3 approach to creating customizable generic functions,
but it's a shame that there's no way of declaring a default function that
works for all instances of the base classe(s).  Or maybe I just didnt find
out how to do that yet?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/generics/attachments/20070630/fbe66259/attachment.htm


More information about the Generics mailing list