I have data defined as below:
data FGM a = Pure a | GMAction Integer Integer (PlayerMsg -> FGM a)
data PlayerMsg = Guess Integer | Surrender
deriving (Eq, Show)
FGM represents a number guessing game where the 2 integers are the upper and lower bounds, a is the value to be returned in the end, and playermsg is the guess that the player makes.
I would like to make FGM a Functor, so I'm trying to define a fmap for it. Problem is I don't know how do deal with the (PlayerMsg -> FGM a) part of FGM.
From my understanding of the testcases given, for fmap g (someFGM), g should only be applied to Pure, if it's GMAction, fmap should use PlayerMsg and generate the next FGM until it reaches a Pure.
This is what I've tried:
instance Functor FGM where
fmap g (Pure a) = Pure (g a)
fmap g (GMAction upper lower thing) = GMAction upper lower (fmap g (\x -> case (thing x) of
Pure a -> Pure a
GMAction u l t -> GMAction u l t))
But when I try to run test on this I get this error:
Occurs check: cannot construct the infinite type:
b ~ FGM b
Expected type: PlayerMsg -> FGM b
Actual type: PlayerMsg -> b
In the third argument of 'GMAction', namely '(fmap g (\x -> case (thing x) of
Pure a -> Pure a
GMAction u l t -> GMAction u l t))'
In the expression:...
I've also tried
fmap g (GMAction upper lower thing) = GMAction upper lower (fmap g thing)
and got the same error.
I tried to search for examples with data that has a function as parameter like PlayerMsg -> FGM a, but can't find anything. this is kind of similar but didn't work for me(it's my first failed example). Can someone help me define this fmap or point me at where to learn about this?
thing. - duplode