I have a data type called Interaction which is as follows:
data Interaction = Interaction AgentID AgentID Action Action
deriving Show
I have a function which is designed to get the Action of the other agent (i.e. not "me") given an interaction:
getCounterAgentAction :: AgentID -> Interaction -> Maybe Action
getCounterAgentAction me (Interaction a b x y)
| a == me = Just y
| b == me = Just x
| otherwise = Nothing
But I'd really like to get rid of the Maybe here and enforce that Interaction is an Interaction which contains the given AgentID (I guarantee this at runtime elsewhere in the codebase. Is there a way of doing this?
Some more context (updated)
This code is part of an evolutionary game-theory simulator. Each Interaction encodes how a pair of Agents interacted in a given frame of the simulator (which is basically a time-slice or "round" of the game). In order to calculate the scores, I need to understand how the Agents behaved, and so for each Agent, I check how they interacted with every other Agent. Therefore when I pass an Interaction to this scoring function, I'd like to be able to guarantee that the interactions I am passing have the AgentID I'm checking against in one of the fields. I already know they do at runtime because I'm filtering [Interaction] for those with that AgentID using this function:
findMyInteractions :: AgentID -> [Interaction] -> [Interaction]
findMyInteractions me = filter (\ (Interaction a b _ _) -> (a==me) || (b==me))
It seems to me, therefore, that my use of Maybe could be eliminated here if only I could somehow encode in the types that an Interaction is an Interaction of a given AgentID.