[Haskell-cafe] type variable in class instance

oleg at okmij.org oleg at okmij.org
Tue Sep 11 08:53:32 CEST 2012


Corentin Dupon wrote about essentially the read-show problem:
> 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 ()

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

> case cast event of
>    Just (Message s::Message ()) -> putStrLn $ show s
>    Nothing -> return ()

(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

> 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





More information about the Haskell-Cafe mailing list