[Haskell-cafe] Reading open data types
Hi all, We've had a discussion on #haskell about how we can make a function that reads in serialized values of an open data type, such as class (Show a, Read a) = MyClass a where typeTag :: a - String ... operations on the open data type... data Obj = forall a. MyClass a = Obj { unObj :: a } We would like to write a function like, oread :: String - Obj The problem here is that unlike with 'read,' the calling context of 'oread' does not fix the implementation of Read that we want to use. The best we've been able to come up with was to build a table that maps type names to types: type TypeTable = Map String Obj oread :: TypeTable - String - Obj oread types s = Obj $ read repr `asTypeOf` unObj (types ! tag) where tag = takeWhile (/= ' ') s repr = drop 1 $ dropWhile (/= ' ') s instance Show Obj where show (Obj x) = typeTag x ++ ++ show x As far as we can see, we'll have to create this table manually, without support from the compiler. My suggestion would be to put the code constructing the table for each module at the top of that module, to keep it together with the exports and imports, like this: module Foo.Foo (export1, export2, fooFooTypes) where import Foo.Bar import Foo.Baz import Data.Map fooFooTypes = fooBarTypes `union` fooBazTypes `union` fromList [ (Foo.Foo.Ty1, Obj (undefined :: Ty1)) , (Foo.Foo.Ty2, Obj (undefined :: Ty2)) ] However, this is still kind of boring. Is there a better way? If not, would it be a good idea to have compiler support for building this kind of type table? Thanks, - Benja ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Reading open data types
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 Benja Fallenstein wrote: Hi all, We've had a discussion on #haskell about how we can make a function that reads in serialized values of an open data type, such as [...] However, this is still kind of boring. Is there a better way? If not, would it be a good idea to have compiler support for building this kind of type table? Since Show instances can overlap (e.g. (show (1::Int)) == (show (1::Integer))), we need to tag with the type. Reminds me of Typeable. Since GHC lets us derive Typeable with a guarantee of different types being distinct (at least for a single compile-and-run session...), maybe that can be leveraged somehow? (I see that was sort of mentioned in the IRC discussion) Isaac -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGcAyNHgcxvIWYTTURAlI5AKC8bdbK/oL+B3Btlox9hfP4Lga1GwCgliZu Vi+be1mSEZnsoSAm3VgNaHo= =1x5R -END PGP SIGNATURE- ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Reading open data types
Hi Isaac, 2007/6/13, Isaac Dupree [EMAIL PROTECTED]: Since Show instances can overlap (e.g. (show (1::Int)) == (show (1::Integer))), we need to tag with the type. Indeed. But that's the easy part :-) Reminds me of Typeable. Since GHC lets us derive Typeable with a guarantee of different types being distinct (at least for a single compile-and-run session...), maybe that can be leveraged somehow? We can perhaps use it to go from the type to the type tag, but as far as I understand we can not, unfortunately, use it to go from the type tag to the type. (We *may* be able to use the TypeRep as the key of the map I proposed in my earlier mail, but we can't use it to replace the map, afaiu.) The problem is that, in the type system, a TypeRep is not actually associated with the type that it represents, nor is there (afaik) an internal table that associates TypeReps with the types they represent. In Data.Generics, there are some functions that let you take a DataTypeRep and use it to create a value of the corresponding type. However, the code doesn't use the DataTypeRep to get the type. The relevant function looks like this: fromConstr :: Data a = Constr - a Like 'read' gets the 'Read' instance, this gets the 'Data' instance from its return type (you have to call it in a context that constrains the return type). So, you can *not* use it to write a function like this: data D = forall a. Data a = D a fromConstrD :: Constr - D because, in the type system, you wouldn't be able to use the Constr to get the Data instance corresponding to the Constr's TypeRep. Hope that makes sense ... I'm not explaining it too well :-/ Thanks, - Benja ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Reading open data types
Hello Benja, Wednesday, June 13, 2007, 6:12:25 PM, you wrote: We've had a discussion on #haskell about how we can make a function that reads in serialized values of an open data type, such as look at Data.Generics.Text which may be implements exactly what you need -- Best regards, Bulatmailto:[EMAIL PROTECTED] ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Reading open data types
Hi Bulat, 2007/6/13, Bulat Ziganshin [EMAIL PROTECTED]: We've had a discussion on #haskell about how we can make a function that reads in serialized values of an open data type, such as look at Data.Generics.Text which may be implements exactly what you need Unfortunately not. Data.Generics.Text provides gread :: Data a = ReadS a That is, you have to constrain its return type to the particular type you want to read. What I'm looking for is a way to read any type implementing a certain class (deciding the type to use based on a type tag) and returning the result in an existential wrapper. - Benja ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Reading open data types
On Wed, Jun 13, 2007 at 05:12:25PM +0300, Benja Fallenstein wrote: However, this is still kind of boring. Is there a better way? If not, would it be a good idea to have compiler support for building this kind of type table? The compiler does build exactly such a table - it's called a symbol table. If you aren't afraid of massive overkill, you can use hs-plugins to write String - exists a. Read a = a . Stefan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Reading open data types
2007/6/14, Stefan O'Rear [EMAIL PROTECTED]: On Wed, Jun 13, 2007 at 05:12:25PM +0300, Benja Fallenstein wrote: However, this is still kind of boring. Is there a better way? If not, would it be a good idea to have compiler support for building this kind of type table? The compiler does build exactly such a table - it's called a symbol table. If you aren't afraid of massive overkill, you can use hs-plugins to write String - exists a. Read a = a . Now *there* is an idea. :-) Hah. Massive overkill, indeed, but you'd call 'eval' only once for every type tag, of course, and cache the result, so the overhead would be O(1) per run of the application. - Benja ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe