Deconstruyendo un tipo existencial
Estoy utilizando un tipo existencial como un envoltorio. En un punto de mi código en el que conozco el tipo adjunto, quiero hacer algo con él que sea específico al tipo adjunto. Esto es lo más cercano que puedo conseguir:
{-# LANGUAGE ExistentialQuantification #-}
class Agent a where
agentId :: a -> String
speciesId :: a -> String
-- plus other functions that all agents support
-- | A wrapper allowing my daemon to read and write agents of any species.
-- (Agents are stored in files that contain a tag so I know which function
-- to call to read the agent.)
data AgentBox = forall a. Agent a => AgentBox { unbox :: a }
instance Agent AgentBox where
agentId (AgentBox a) = agentId a
speciesId (AgentBox a) = speciesId a
-- plus other functions that all agents support
bugTag :: String
bugTag = "Bug"
data Bug = Bug String
instance Agent Bug where
agentId (Bug name) = name
speciesId _ = bugTag
doSomethingWith :: AgentBox -> IO ()
doSomethingWith a = do
if speciesId a == bugTag
then do
-- Now I know it's a bug, and I want to do something bug-specific
doBugStuff2 a
return ()
else return ()
doBugStuff :: Bug -> IO ()
doBugStuff a = putStrLn $ agentId a ++ " does bug stuff"
doBugStuff2 AgentBox{unbox=a} = doBugStuff (a `asTypeOf` model) -- line 39
where model = undefined :: Bug
El error que recibo es:
Amy30.hs:39:45:
Could not deduce (a ~ Bug)
from the context (Agent a)
bound by a pattern with constructor
AgentBox :: forall a. Agent a => a -> AgentBox,
in an equation for `doBugStuff2'
at Amy30.hs:39:13-29
`a' is a rigid type variable bound by
a pattern with constructor
AgentBox :: forall a. Agent a => a -> AgentBox,
in an equation for `doBugStuff2'
at Amy30.hs:39:13
In the first argument of `asTypeOf', namely `a'
In the first argument of `doBugStuff', namely
`(a `asTypeOf` model)'
In the expression: doBugStuff (a `asTypeOf` model)
Failed, modules loaded: none.
¿Cómo puedo lograr esto? Gracias de antemano por cualquier sugerencia.