Consider this code:
{-# language FlexibleInstances, UndecidableInstances #-}
module Y where
class C m where
x :: m
instance {-# overlappable #-} Monoid m => C m where
x = mempty
instance C Int where
x = 53
What is the type of x
?
λ :type x
x :: C m => m
So far — so good. Now remove the Int
instance. What is the type of x
?
λ :type x
x :: Monoid m => m
Surprise!
Why is this happening?
The triple constraint theory, also called the Iron Triangle in project management, defines the three elements (and their variations) as follows: Scope, time, budget. Scope, schedule, cost.
A constraint, in project management, is any restriction that defines a project's limitations; the scope, for example, is the limit of what the project is expected to accomplish.
Basically, the Triple Constraint states that the success of the project is impacted by its costs, time, and scope. As a project manager, you can keep control of the triple constraint by balancing these three constraints through trade-offs.
For example, when you set a deadline for the project to be completed and released, you have given the project a time constraint. The triple constraint theory says that every project will include three constraints: budget/cost, time, and scope. And these constraints are tied to each other.
This behaviour is explained in the following blog post:
In short: GHC is smart enough to see that you have only one instance of the C
typeclass and decided that it's the only possible instance, so every time it sees C m
constraint, it replaces it with Monoid m
because they are equivalent.
N.B. As @chi further explains in a comment:
When GHC finds a constraint C t
, it tries to solve it. If if finds a matching instance (...) => C t where ...
, the constraint is replaced with the context (...)
. This is repeated as much as possible. The final constraint appears in the type (or triggers a "unsolved" type error). This process is justified since there can only be at most one matching instance. Overlapping instances change this, and prevent this context reduction when multiple instances (in scope!) match, roughly. It is a fragile extension, to be used with some care.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With