Skip to content

Improve errors for recursively-defined type class instances #2975

Description

@cdepillabout

Given the following Foo type:

data Foo = Foo
  { int :: Int
  , foo :: Maybe Foo
  }

I can derive Generic like the following:

derive instance genericFoo :: Generic Foo _

I can even write an instance of Eq for Foo by hand:

instance eqFoo :: Eq Foo where
  eq :: Foo -> Foo -> Boolean
  eq (Foo fooA) (Foo fooB) =
    fooA.int == fooB.int && fooA.foo == fooB.foo

However, I get an error when trying to use genericEq to write the Eq instance:

instance eqFoo :: Eq Foo where eq = genericEq

The error is as follows:

[1/1 CycleInDeclaration] src/Web/Twitter/Test.purs:19:1

  19  instance eqFoo :: Eq Foo where eq = genericEq
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  The value of eqFoo is undefined here, so this reference is not allowed.

Is this a deficiency in the compiler? Or simply a short-coming of Generic? Or maybe just a limitation with recursive types in a strict language?

If this is a limitation with Generic and not a compiler issue, it would be nice to get a better error message from the compiler. I didn't really understand what the error message was talking about until I played around with the code a little:

The value of eqFoo is undefined here, so this reference is not allowed.

I mean, it makes sense now that I know what it is talking about, but it would have been more clear/obvious if it said something like:

It is not possible to use genericEq with Foo because Foo is a recursive datatype.


Here is a repository with some code to play around with if you want to reproduce the issue:

https://github.com/cdepillabout/purescript-twitter-types/blob/16b5cfe7a55d1f23d12f6b87766abff31bf665ad/src/Web/Twitter/Test.purs

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions