It seems like I should be exact as possible with type signatures as I'm learning. For example I was using:
doWeight :: (ServerMonad m) => String -> m Response
which is all fine and good, until I change the String into a
. Then I ran into some compilation errors and I figured it was with my Maybe plumbing or maybe the IO of the database connection. My compilation error was
Ambiguous constraint `ServerMonad m'
At least one of the forall'd type variables mentioned by the constraint
must be reachable from the type after the '=>'
In the type signature for `doWeight':
doWeight :: (ServerMonad m) => ServerPartT IO Response
Failed, modules loaded: Config, StatsDal, Stats, FiveBeeX, WeightView.
It seems like the biggest clue, which I often miss, is to pay attention to every part of the compilation error message.... what line and character? Ambiguous
constraint... and then the hint of the actual type signature
ServerPartT IO Response
After fumbeling around, I remembred by looking at another one of my function type signatures that m Response was indeed ServerPartT IO Response, so without changing the implementation, but just the type signature to
doWeight :: Maybe Stats -> ServerPartT IO Response
everything compiles and works. I'm just so used to the issue being the implementation, maybe always being explicit with the Type signature will reduce these compilation errors and red herrings.