<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) =&gt; Event e

data Player     = Player Int         deriving (Typeable)
data Message m  = Message String     deriving (Typeable)

instance  Event Player

instance (Typeable m) =&gt; Event (Message m)

viewEvent :: (Event e) =&gt; e -&gt; IO ()
viewEvent event = do
    case cast event of
        Just (Player a) -&gt; putStrLn $ show a
        Nothing -&gt; return ()
    case cast event of
        Just (Message s) -&gt; putStrLn $ show s
        Nothing -&gt; 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 ()) -&gt; putStrLn $ show s
   Nothing -&gt; 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    -&gt; Event Player
    Message :: String -&gt; Event (Message s)

viewEvent :: Event e -&gt; 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>