[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