Skip to content

Instantly share code, notes, and snippets.

@Wizek
Last active May 26, 2018 20:13
Show Gist options
  • Save Wizek/396b0a608fa93d7d458a78dbf7c88870 to your computer and use it in GitHub Desktop.
Save Wizek/396b0a608fa93d7d458a78dbf7c88870 to your computer and use it in GitHub Desktop.

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.

Edit 2018-05-26:

Some further relevant detains can be found over on this StackOverflow question.

@Wizek
Copy link
Author

Wizek commented Nov 10, 2017

Thanks @mrkgnao for your comment, and sorry for my belated reply. I unfortunately don't yet see how your example is applicable in my case above.

For one, for instance, my type error mentions the mysterious is as general as its infrared signature bit, which I don't see in your example. Can you make your example include that in its error? Or tell me what that means in my code?

For second, as you show, you can actually attempt to execute the ill-typed deferred-errorful code by:

<λ> show (read "5")
"*** Exception: Prelude.read: no parse

And I believe my example produces the type error in a dead-code section: meaning it could actually never be reached. I suspect the compiler is preventing a valid program from compiling. If you suspect the opposite, could you perhaps show how this deferred type error could be reached in my example?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment