Reputation: 1019
I've been getting some strange typeclass errors of the form "No instance for (Test a0) arising from an expression type signature". Here is the simplest version of the offending code I could come up with:
class Test a where
test :: a
foo = test
Adding the type doesn't help:
foo = test :: Test a => a
However, adding an instance of Test does make it compile:
instance Test Int where
test = 0
This isn't really acceptable, as I want my instances declared elsewhere.
Finally, passing -XNoMonomorphismRestriction
to ghc(i) also allows it to compile. While this is good enough for now, I don't understand what this extension does, why it is necessary, or what downsides may be lurking.
Upvotes: 4
Views: 166
Reputation: 1019
After reading this article I finally understood the monomorphism restriction. The point is that things which look like constants shouldn't be polymorphic, as that might cause them to be evaluated multiple times (at worst resulting in exponential slowdowns).
In my actual case the "constant" was itself a function (via currying). I'm now on the fence; should I resort to -XNoMonomorphismRestriction
, or add the type declaration? The latter seems less drastic/intrusive, but on the other hand I just don't like what the MR does to my types.
Upvotes: 1
Reputation: 18199
As an alternative to disabling the monomorphism restriction for the whole file (which is fairly harmless, but can cause some unexpected recalculation of values that are not intended to be polymorphic), adding the type does help, but you have to do it as a signature at top level:
foo :: Test a => a
foo = test
If you add it just after test
, it is considered just an annotation on the subexpression test
, and does not turn off the monomorphism restriction for foo
itself.
Upvotes: 10