Try commenting out line 21 in ./test-suite/HsDiExample/MainSpec.hs
21: & override "logger" [qc| \a -> modifyIORef logs (++ [a]) |]
Run it with stack test
, and you'll get an error like the following:
• Ambiguous type variable ‘m0’
prevents the constraint ‘(Monad m0)’ from being solved.
• When checking that the inferred type
logger :: forall b t (m :: * -> *).
Monad m =>
Data.Text.Internal.Text -> IO ()
is as general as its inferred signature
logger :: Data.Text.Internal.Text -> IO ()
But! This is not a true type error in the sense that we like; that it would catch an invalid program that otherwise would fail with a run-time error. It's not, because deferring the error (with -fdefer-type-errors
) causes the program (and test executable) to compile, link and execute without a problem!
The assertions do fail, but that's to be expected when we disable a mock, so it's beside the point. The point is that we don't run into the deferred typeerror exception.
So, it would seem to me that this type error is complaining about a vagueness in a portion of a piece of dead code that could never execute.
And perhaps if we could write default (IO)
or default (Identity)
then we could satisfy the compiler. Similar to how default (Text)
appeases it when we have an unused binding of foo = "bar"
with -XOverloadedStrings
.
At least, that's as much as I understand of it at the moment. (1) I'd love for anyone to tell me more about what is as general as its inferred signature
type errors supposed to mean. And/or (2) please show me a counterexample where the deferred-exception-producing part of the code can be reached. And/or, perhaps most appreciatedly, (3) please tell me what change could I make to hs-di-example or even hs-di that could alleviate having to defer type errors for the sake of the compiler every now and then.
Some further relevant detains can be found over on this StackOverflow question.
This is probably similar to the "
show . read
" problem, which can reliably be made to trigger anerror
in case defaulting is disabled. Here, again, we have a type variable that isn't present in the type of the complete expression:Here's an example in GHCi.