Skip to content

Infinite loop while resolving instances #89

Open
@AlexKnauth

Description

@AlexKnauth

Running a program where deriving instances produces a cycle gets into an infinite loop.
Here the (C (List Integer)) instance produces the subgoal (C (Tuple Integer (List Integer))), which produces the subgoals (C Integer) and (C (List Integer)). It doesn't recognize that the (C (List Integer)) subgoal is what it was originally trying to solve, and stop the loop.

As an aside, the vanilla Haskell version of this errors saying

• Non type-variable argument in the constraint: C (a, [a])
(Use FlexibleContexts to permit this)

Unless I use both FlexibleContexts and UndecidableInstances.

There are several ways Hackett could "fix" this.
(1) By disallowing non-type-variable arguments in constraints, like Haskell does without FlexibleContexts.
(2) By recognizing the cycle and erroring, like Haskell does with FlexibleContexts but without UndecidableInstances.
(3) By letting it through somehow, like Haskell does with both FlexibleContexts and UndecidableInstances.

But it should not both let the ∀ [a] (C (Tuple a (List a))) => (C (List a)) instance through and loop when it tries to use it.

#lang hackett

(class (C a)
  [c : {a -> Integer}])

(instance (C Integer) [c id])
(instance (∀ [a b] (C a) (C b) => (C (Tuple a b)))
  [c (λ* [[(Tuple a b)] {(c a) + (c b)}])])

(instance (∀ [a] (C (Tuple a (List a))) => (C (List a)))  ; this "goes through" fine
  [c (λ* [[Nil] 0]
         [[{fst :: rst}] (c (Tuple fst rst))])])

(c (List 1 2 3 4))  ; this causes the infinite loop

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions