Skip to content

Better inferred signatures

Consider this (taken from here)

class FieldType x r ~ a => HasField (x :: k) r  a where
  type FieldType x r
  getField :: r -> a
  setField :: r -> a -> r

f r = setField @"bar" r (getField @"foo" r)

We get this type inferred for f:

  f :: forall r.
       (HasField "bar" r (FieldType "bar" r),
        HasField "foo" r (FieldType "bar" r))
     => r -> r

But actually this signature is equivalent

  f :: forall r a.
       (HasField "bar" r a, HasField "foo" r a)
     => r -> r

and it's quite a bit shorter. Similarly, from this definition

g r = setField r

We get this inferred type

  g :: forall r p.
       HasField "bar" r (FieldType "bar" r)
    => p -> r -> FieldType "bar" r -> r

where again we might prefer

  g :: forall r a. HasField "bar" r a => r -> a -> r

Question: could we make GHC infer the briefer types?

After all, it does some similar abbreviation with type classes. Where we could infer (Ord a, Eq a) we collapse out the Eq a and just infer the context (Ord a).

There is nothing record-specific about this ticket. It's just about using inferred equality constraints to simplify the inferred signature.

Trac metadata
Trac field Value
Version 8.6.3
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information