
"C. McCann"
This was my first thought as well! However, reading to/from a file would of course be in IO, at which point you'd be free to read the file back in through normal means to get at the representation. So in that respect, this is equivalent to (a -> b) -> IO String.
IMO, it's morally different, you're now operating on a file, and you shouldn't rely on the contents being predictable. You can make the sin-bin argument that IO can do anything, but I think there's a moral distinction between serialize :: a -> IO ByteString x <- serialize f and serialize :: a -> Opaque store :: Opaque -> FilePath -> IO () do x <- serialize f store x n B.readFile n You could probably already snarf chunks of the heap and dump them to file.
I suppose one could object that this isn't actually serializing anything at all; to which I would respond that, in pure code, how do you expect to tell the difference?
Nice one :-) I guess the real question is what are the useful, pure operations on an opaque type that can contain arbitrary functions. -k -- If I haven't seen further, it is by standing in the footprints of giants