Reputation: 61121
I am trying to create an "agent-like" object, that, given an two indices (agent index, alternative index) returns it's preference for that alternative.
My error is:
Couldn't match expected type `Integer'
with actual type `RandomAgent'
In the first argument of `preference', namely `agentNum'
In the expression: preference agentNum alternative
In an equation for `score':
score agentNum alternative = preference agentNum alternative
What I am trying to have is a piece of code that essentially represents a mathematical function such as A_i(x_j)
where A_i
is the agent's "score" function for the alternative x_j
.
I would appreciate any hints on how to proceed. Maybe there is a simpler approach...
Full code below for signatures of other functions
module AgentGenerator where
import System.Random
type Alternative = Integer
data RandomAgent = RandomAgent
class Agent a where
score :: a -> Alternative -> Double
instance Agent RandomAgent where
score agentNum alternative = preference agentNum alternative
-- TODO: Replace Doubles with Agents
-- Generate `n` agents with `x` alternatives each
generate :: Integer -> Integer -> [Double]
generate agents alternatives = [ preference i j | i <- [0..(agents-1)], j <- [0..(alternatives-1)] ]
-- Given agent's index and alternative's index return that agent's
-- preference for that alternative
preference :: Integer -> Integer -> Double
preference agent alternative = randomFromSeed $ fromCoord (agent, alternative)
-- Given grid position convert it to a single integer
fromCoord :: (Integer, Integer) -> Integer
fromCoord (agent, alternative) = (agent * 10^0) + (alternative * 10^1)
-- Generate random value between [0, 1] based on the seed
randomFromSeed :: Integer -> Double
randomFromSeed seed = value
where (value, gen) = randomR (0.0, 1.0) $ mkStdGen (fromIntegral seed)
Upvotes: 0
Views: 678
Reputation: 47062
class Agent a where ...
You define a class called Agent
...
instance RandomAgent Integer where ...
...then you declare that Integer
implements the RandomAgent
class.
Do you mean to declare a type called RandomAgent
, containing an Integer
field, and implementing the Agent
class? You do that in two steps:
data RandomAgent = RandomAgent Integer -- first declare your RandomAgent type
instance Agent RandomAgent where -- then declare that it implements your Agent class
score agent alternative = preference agent alternative
(As you're still thinking in OOP terms, I am obliged to point out that you may not need a class (and if you only have a single type implementing your class, you certainly don't)... but if you do, that's how you do it.)
Answer the second:
Your preference
function expects an Integer
as its first parameter, but is actually given a RandomAgent
by score
. One or other of the functions is going to have to deconstruct (think “unwrap”) the RandomAgent
and extract the Integer
field within.
You might do it in your score
function like this:
instance Agent RandomAgent where
score (RandomAgent agentNum) alternative = preference agentNum alternative
OR you might do it in your preference
function like this:
preference :: RandomAgent -> Integer -> Double
preference (RandomAgent agent) alternative = randomFromSeed $ fromCoord (agent, alternative)
Obviously, don't make the changes in both functions, otherwise you'll find yourself passing an Integer
where a RandomAgent
is required.
Upvotes: 2