<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<div class="moz-cite-prefix">On 11-09-12 08:53, <a class="moz-txt-link-abbreviated" href="mailto:oleg@okmij.org">oleg@okmij.org</a>
wrote:<br>
</div>
<blockquote cite="mid:20120911065332.1997.qmail@www1.g3.pair.com"
type="cite">
<pre wrap="">
Corentin Dupon wrote about essentially the read-show problem:
</pre>
<blockquote type="cite">
<pre wrap="">class (Typeable e) => Event e
data Player = Player Int deriving (Typeable)
data Message m = Message String deriving (Typeable)
instance Event Player
instance (Typeable m) => Event (Message m)
viewEvent :: (Event e) => e -> IO ()
viewEvent event = do
case cast event of
Just (Player a) -> putStrLn $ show a
Nothing -> return ()
case cast event of
Just (Message s) -> putStrLn $ show s
Nothing -> return ()
</pre>
</blockquote>
<pre wrap="">
Indeed the overloaded function cast needs to know the target type --
the type to cast to. In case of Player, the pattern
(Player a) uniquely determines the type of the desired value: Player.
This is not so for Message: the pattern (Message s) may correspond to
the type Message (), Message Int, etc.
To avoid the problem, just specify the desired type explicitly
</pre>
</blockquote>
I had the same idea, but it doesn't work. Fixing m to () causes the
cast to fail for any other type, so <font face="Courier New,
Courier, monospace">viewEvent (Message "yes" :: Message ())</font>
will work, but <font face="Courier New, Courier, monospace">viewEvent
(Message "no" :: Message Char)</font><br>
won't. <br>
<br>
Putting viewEvent in the Event class though, like Ryan suggested,
seems to be an elegant solution that stays close to the original
source.<br>
<br>
Cheers,<br>
Martijn<br>
<br>
<blockquote cite="mid:20120911065332.1997.qmail@www1.g3.pair.com"
type="cite">
<pre wrap="">
</pre>
<blockquote type="cite">
<pre wrap="">case cast event of
Just (Message s::Message ()) -> putStrLn $ show s
Nothing -> return ()
</pre>
</blockquote>
<pre wrap="">
(ScopedTypeVariables extension is needed). The exact type of the
message doesn't matter, so I chose Message ().
BTW, if the set of events is closed, GADTs seem a better fit
</pre>
<blockquote type="cite">
<pre wrap="">data Player
data Message s
data Event e where
Player :: Int -> Event Player
Message :: String -> Event (Message s)
viewEvent :: Event e -> IO ()
viewEvent (Player a) = putStrLn $ show a
viewEvent (Message s) = putStrLn $ show s
</pre>
</blockquote>
<pre wrap="">
_______________________________________________
Haskell-Cafe mailing list
<a class="moz-txt-link-abbreviated" href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a>
<a class="moz-txt-link-freetext" href="http://www.haskell.org/mailman/listinfo/haskell-cafe">http://www.haskell.org/mailman/listinfo/haskell-cafe</a>
</pre>
</blockquote>
<br>
</body>
</html>