
Is is possible to read/show an existentially typed list? Would it be possible if, instead of using read/show, I defined some variant that relies on the typeof/typeable infrastructure? Is there a way to read in a typename for use in coercing a read? -Alex- _________________________________________________________________ S. Alexander Jacobson mailto:me@alexjacobson.com tel:917-770-6565 http://alexjacobson.com

S. Alexander Jacobson
Is is possible to read/show an existentially typed list?
Would it be possible if, instead of using read/show, I defined some variant that relies on the typeof/typeable infrastructure? Is there a way to read in a typename for use in coercing a read?
Dylan Thurston and I encountered this problem a while ago. Show is easy: just use a type like "exists a. Show a => ...". Read is hard, because one needs to get the Read dictionary from somewhere, and the dynamic typing facility in Haskell does not include type-class constraint reduction at runtime. The best solution we came up with was to replace the existentially typed list with a list of string-string pairs, where the first string names the type and the second string names the value. The call to "read" is only done at lookup time, not at file-reading time. -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig Be it declared and enacted by this present Parliament / That the People of England / are / a Commonwealth and free State / without any King or House of Lords. -- An Act declaring England to be a Commonwealth 1649-05-19 | 355 years | 2004-05-19 http://tinyurl.com/2dqnh

Ok, but it sounds like you need to know the list of possible types in advance. Is it possible to have a lib take a filepath and type name as an arbitrary string, and read the instance in? The context here is that I'm writing an App Server (tentative name: HAppS) that given an instance of: class (Eq state, Read state,Show state ,Eq request, Read request, Show request) => App state request response where startState::state execRequest::state-> CallBack state -> Chan a -> ReqContext request -> Result state response takes an arbitrary state, does write-ahead logging of any requests that change that state, and periodically saves the state to disk. If the computer dies or is shutdown for any reason, the last saved state is read-back from disk and the log is replayed until state is current, at which point, new requests may be processed. (Think Prevayler, but with side-effects and state saving handled properly -- thanks to Haskell's type system!) To use this lib, you do: main = (serveApp requestProducer filepaths)::YourAppInstance serveApp then attempts to read in the state from the filepaths and calls startState otherwise. The explicit type here coerces serveApp to read or startState the proper type (serveApp returns the state eventually). The problem is that the type of requestProducer is sort of complex (simplifying): type ReqProd=(((Respond, request) -> IO ()) -> IO t) type Respond response = response -> IO () It is a function that takes a function that writes (respond,request) pairs to a channel and when run, calls that function periodically to interact with state. I find this is a bit hard to understand (and I just wrote the code!). I'd really like serveApp to return the writeChannel function and then have the client code call it. Then calling serveApp would look like: main = do queueReuest <- serveApp filePaths "YourAppInstance" Even better, I'd love to have the same app be able to handle multiple request types (via existential types), but right now, thats not possible because I need to be able to (read) them. -Alex- _________________________________________________________________ S. Alexander Jacobson mailto:me@alexjacobson.com tel:917-770-6565 http://alexjacobson.com On Mon, 26 Apr 2004, Chung-chieh Shan wrote:
S. Alexander Jacobson
wrote in article in gmane.comp.lang.haskell.cafe: Is is possible to read/show an existentially typed list?
Would it be possible if, instead of using read/show, I defined some variant that relies on the typeof/typeable infrastructure? Is there a way to read in a typename for use in coercing a read?
Dylan Thurston and I encountered this problem a while ago. Show is easy: just use a type like "exists a. Show a => ...". Read is hard, because one needs to get the Read dictionary from somewhere, and the dynamic typing facility in Haskell does not include type-class constraint reduction at runtime. The best solution we came up with was to replace the existentially typed list with a list of string-string pairs, where the first string names the type and the second string names the value. The call to "read" is only done at lookup time, not at file-reading time.
-- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig Be it declared and enacted by this present Parliament / That the People of England / are / a Commonwealth and free State / without any King or House of Lords. -- An Act declaring England to be a Commonwealth 1649-05-19 | 355 years | 2004-05-19 http://tinyurl.com/2dqnh
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 2004-04-28T15:12:03-0400, S. Alexander Jacobson wrote:
Ok, but it sounds like you need to know the list of possible types in advance. Is it possible to have a lib take a filepath and type name as an arbitrary string, and read the instance in?
I don't think you need to know the list of possible types in advance. Here is some (only slightly tested) code: import Data.Dynamic import Maybe import Monad lookupRead :: (Eq key, Read val, Typeable val) => key -> [(key, (String, String))] -> Maybe val lookupRead key list = ret where ret = case lookup key list of Just (typ, val) -> if typ == show (typeOf (fromJust ret)) then case reads val of [(v,"")] -> Just v _ -> Nothing else Nothing _ -> Nothing The question is how to get the result of lookupRead memoized, so that the call to reads happens at most once for each entry in the list. -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig BBC News: Universities face week of protest http://news.bbc.co.uk/1/hi/education/3508209.stm

I don't think this works. I just tried it with: main = print $ lookupRead 1 [(1,("Integer","100"))] How would Haskell know that typ actually does equal typeOf? -Alex- _________________________________________________________________ S. Alexander Jacobson mailto:me@alexjacobson.com tel:917-770-6565 http://alexjacobson.com On Wed, 28 Apr 2004, Chung-chieh Shan wrote:
On 2004-04-28T15:12:03-0400, S. Alexander Jacobson wrote:
Ok, but it sounds like you need to know the list of possible types in advance. Is it possible to have a lib take a filepath and type name as an arbitrary string, and read the instance in?
I don't think you need to know the list of possible types in advance. Here is some (only slightly tested) code:
import Data.Dynamic import Maybe import Monad
lookupRead :: (Eq key, Read val, Typeable val) => key -> [(key, (String, String))] -> Maybe val lookupRead key list = ret where ret = case lookup key list of Just (typ, val) -> if typ == show (typeOf (fromJust ret)) then case reads val of [(v,"")] -> Just v _ -> Nothing else Nothing _ -> Nothing
The question is how to get the result of lookupRead memoized, so that the call to reads happens at most once for each entry in the list.
-- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig BBC News: Universities face week of protest http://news.bbc.co.uk/1/hi/education/3508209.stm

On 2004-04-28T23:33:31-0400, S. Alexander Jacobson wrote:
I don't think this works. I just tried it with: main = print $ lookupRead 1 [(1,("Integer","100"))]
This fails for the same reason print $ read "100" fails. You need to give a type signature to avoid type-class instance ambiguity: main = print $ (lookupRead 1 [(1,("Integer","100"))] :: Maybe Integer) On GHCi 6.2.1, the above yields "Just 100" for me. -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig Be it declared and enacted by this present Parliament / That the People of England / are / a Commonwealth and free State / without any King or House of Lords. -- An Act declaring England to be a Commonwealth 1649-05-19 | 355 years | 2004-05-19 http://tinyurl.com/2dqnh

But isn't the point of this code that you don't need that type signature? If I knew in advance that it was an Integer then I wouldn't need to passs "Integer" in the list. -Alex- On Thu, 29 Apr 2004, Chung-chieh Shan wrote:
On 2004-04-28T23:33:31-0400, S. Alexander Jacobson wrote:
I don't think this works. I just tried it with: main = print $ lookupRead 1 [(1,("Integer","100"))]
This fails for the same reason
print $ read "100"
fails. You need to give a type signature to avoid type-class instance ambiguity:
main = print $ (lookupRead 1 [(1,("Integer","100"))] :: Maybe Integer)
On GHCi 6.2.1, the above yields "Just 100" for me.
-- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig Be it declared and enacted by this present Parliament / That the People of England / are / a Commonwealth and free State / without any King or House of Lords. -- An Act declaring England to be a Commonwealth 1649-05-19 | 355 years | 2004-05-19 http://tinyurl.com/2dqnh
_________________________________________________________________ S. Alexander Jacobson mailto:me@alexjacobson.com tel:917-770-6565 http://alexjacobson.com

On 2004-04-29T11:50:48-0400, S. Alexander Jacobson wrote:
But isn't the point of this code that you don't need that type signature? If I knew in advance that it was an Integer then I wouldn't need to passs "Integer" in the list.
In the context in which the code was originally written, the point was not that you don't need that type signature. Your comment above helped me understand what you want, I think. -- Edit this signature at http://www.digitas.harvard.edu/cgi-bin/ken/sig BBC News: Universities face week of protest http://news.bbc.co.uk/1/hi/education/3508209.stm

So let me ask this question a different way. Is it possible to use Read/Show or Typeable with Existential types. Given MyClass and MyType as follows: class (Read a,Show a,Typeable)=>MyClass a where foo::a type MyType = forall a. MyClass a=> [a] Is there a way to persist MyType? My suspicion is that there isn't because Haskell knows how to say that a string can't be parsed into a particular type but it does not know how to say that a string can't be parsed into any type that is an instance of a particular class. So, assuming you can't I amn curious to know know if this is an in-principle problem or just an in-fact problem. -Alex- _________________________________________________________________ S. Alexander Jacobson mailto:me@alexjacobson.com tel:917-770-6565 http://alexjacobson.com
participants (4)
-
Chung-chieh Shan
-
S. Alexander Jacobson
-
S. Alexander Jacobson
-
S. Alexander Jacobson