Hacker Public Radio

HPR2908: Modeling opinions in space game


Listen Later

We continue with people, this time focusing on opinions. This episode has somewhat more code than previous one, so following along with the shownotes might be a good idea. I’m trying to minimize amount of code I read out aloud.
Intro
One person’s opinion of another is expressed as OpinionScore that ranges from -100 to 100.
Computing the score is based on intelligence player has available to them. Internally we have ReportResult that tracks score, reasons for the score and confidence level about the results. It’s defined as:
data ReportResult =
FeelingLevel OpinionScore
| ReasonsLevel OpinionScore [OpinionReason]
| DetailedLevel OpinionScore [OpinionReason]
deriving (Show, Read, Eq)
We’re going to be adding up these results quite a bit, so we define SemiGroup and Monoid instances for it. When two results are combined, scores are added together, lists of reasons are concatenated and the lowest confidence level is used. This is written as:
instance Semigroup ReportResult where
(FeelingLevel s1) <> (FeelingLevel s2) = FeelingLevel (s1 <> s2)
(FeelingLevel s1) <> (ReasonsLevel s2 _) = FeelingLevel (s1 <> s2)
(FeelingLevel s1) <> (DetailedLevel s2 _) = FeelingLevel (s1 <> s2)
(ReasonsLevel s1 _) <> (FeelingLevel s2) = FeelingLevel (s1 <> s2)
(ReasonsLevel s1 r1) <> (ReasonsLevel s2 r2) = ReasonsLevel (s1 <> s2) (r1 <> r2)
(ReasonsLevel s1 r1) <> (DetailedLevel s2 r2) = ReasonsLevel (s1 <> s2) (r1 <> r2)
(DetailedLevel s1 _) <> (FeelingLevel s2) = FeelingLevel (s1 <> s2)
(DetailedLevel s1 r1) <> (ReasonsLevel s2 r2) = ReasonsLevel (s1 <> s2) (r1 <> r2)
(DetailedLevel s1 r1) <> (DetailedLevel s2 r2) = DetailedLevel (s1 <> s2) (r1 <> r2)
instance Monoid ReportResult where
mempty = DetailedLevel mempty mempty
Opinion based on traits
Current system compares two lists of traits. For example, two brave characters like each other slightly better than if one of them would be coward. Comparison is done by traitPairOpinion function, which definition I’m omitting as it’s rather long and not too interesting. It’s signature is: traitPairOpinion :: TraitType -> TraitType -> Maybe (OpinionScore, OpinionReason). So, given two traits, tells how that pair affects to opinion and reasoning for it.
In order to have nicer format for out data, we introduce a helper function:
traitPairScore :: TraitType -> TraitType -> (OpinionScore, [OpinionReason])
traitPairScore a b =
case traitPairOpinion a b of
Nothing ->
mempty
Just (s, r) ->
(s, [r])
This is because (OpinionScore, OpinionReason) isn’t monoid, but (OpinionScore, [OpinionReason]) is, which means we can combine them with <>.
Actual score calculation based on traits, we do it like this:
traitScore :: [TraitType] -> [PersonIntel] -> [TraitType] -> [PersonIntel] -> ReportResult
traitScore originatorTraits originatorIntel targetTraits targetIntel =
if (Traits `elem` originatorIntel) && (Traits `elem` targetIntel)
then DetailedLevel score reasons
else FeelingLevel score
where
(score, reasons) = mconcat $ traitPairScore <$> originatorTraits <*> targetTraits
The interesting part is mconcat $ traitPairScore <$> originatorTraits <*> targetTraits. Function traitPairScore expects two TraitType values as parameters, but we’re calling it with two li
...more
View all episodesView all episodes
Download on the App Store

Hacker Public RadioBy Hacker Public Radio

  • 4.2
  • 4.2
  • 4.2
  • 4.2
  • 4.2

4.2

34 ratings


More shows like Hacker Public Radio

View all
The Infinite Monkey Cage by BBC Radio 4

The Infinite Monkey Cage

1,952 Listeners

Click Here by Recorded Future News

Click Here

418 Listeners

Hacker And The Fed by Chris Tarbell & Hector Monsegur

Hacker And The Fed

168 Listeners