The problem description
It seems that something has changed in Haskell since the publication of Learn you a Haskell for Great Good. When creating Monads
you not only have to define the Functor
but also now the Applicative
implementation.
In Chapter 14 of the book, in the section on "Making Monads", we define a newtype Prob
like...
newtype Prob a = Prob { getProb :: [(a, Rational)] } deriving Show
and then its Functor
instance...
instance Functor Prob where
fmap f (Prob xs) = Prob $ map (\(x, p) -> (f x, p)) xs
and then the book goes on to define the Monad
instance for it...
flatten :: Prob (Prob a) -> Prob a
flatten (Prob xs) = Prob $ concat $ map multAll xs
where multAll (Prob innerxs, p) = map (\(x,r) -> (x,r*p)) innerxs
instance Monad Prob where
return x = Prob [(x,1%1)]
m >>= f = flatten (fmap f m)
fail _ = Prob []
but I get an error...
• No instance for (Applicative Prob) arising from the superclasses of an instance declaration
• In the instance declaration for ‘Monad Prob’
I've read that the Applicative
instance is now explicitly required and created my solution and wondered if it is correct?
Current attempt at implementing it myself
My implementation is...
instance Applicative Prob where
pure x = Prob [(x, 1%1)]
(Prob xs) <*> (Prob ys) = Prob ([(f y, p * q) | (f, p) <- xs, (y, q) <- ys])
I've done this as the first parameter of the <*>
could be something like Prob [((*3),1%2),((+1),1%2)]
so it would seem that each function in the first parameter would have to be applied to every value in the second parameter and that also the probabilities would have to be dealt with somehow.
Request for answers
Which just seems wrong to me, I don't like that I've pulled out the probabilities like this when the implementation in the book was just automatic and didn't require any of this extra work. I wondered if there is a simpler way to define what I have created or even if this is just wrong in the first place? I feel like there is possibly an fmap
hiding in my Applicative
code somewhere but I'm too new to find it myself.
Even better would be if there is an updated resource for these missing implementations which I've, as yet, been unsuccessful in finding.