Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Constraint on method depends on instances in scope?

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?

like image 622
Ignat Insarov Avatar asked Oct 19 '19 09:10

Ignat Insarov


People also ask

What are the 3 constraints of project management?

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.

What is a scope constraint?

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.

What are the three constraints of a project management why they are critical for project management?

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.

What is the triple constraint of project management give example?

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.


Video Answer


1 Answers

This behaviour is explained in the following blog post:

  • Opaque constraint synonyms

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.

like image 111
Shersh Avatar answered Nov 11 '22 11:11

Shersh