Skip to content

KnownNatN instances are unsafe (in some cases). #12

@nshepperd

Description

@nshepperd

Found this out while trying to set up unary type level functions. It's a consequence of how we look up an instance's constraints at constraintToEvTerm.go.df_args in the solver. For an instance where the type variables are mentioned in the opposite order to where they appear in the instance head, such as:

forall b a. (KnownNat b, KnownNat a) => DKnownNat2 "+" a b

Suppose we're solving for an instance for KnownNat (x + y). We use piResultTys idType [x, y] to apply the type arguments, but that unfortunately substitutes them in the wrong order, ie. b=x, a=y, resulting in (KnownNat x, KnownNat y) => DKnownNat2 "+" y x when the instance we wanted is (KnownNat y, KnownNat x) => DKnownNat2 "+" x y.

You can see this in action by reversing the order of the KnownNat constraints in the definition of KnownNat2 "-".

I think we want to somehow unify the instance head with KnownNat2 "+" x y in order to properly substitute the type variables and get the right instance, but I'm not familiar with GHC api enough to do that easily.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions