Skip to content

PartialTypeSignatures wildcard does not play nice with monomorphic constraints implying orphan instances

Summary

PartialTypeSignature's _ seems to eliminate / not deduce some constraints.

Steps to reproduce

{-# LANGUAGE FlexibleContexts      #-}
{-# LANGUAGE PartialTypeSignatures #-}

module Foo where

class Foo x where
  foo :: x

bar :: (Foo (), _) => f ()
bar = pure foo

baz :: _ => f ()
baz = pure foo

bob :: _ => Foo () => f ()
bob = pure foo

marie :: (Foo x, _) => f x
marie = pure foo

anne :: _ => f x
anne = pure foo

Compiling the above (ghc -c -Wall -Wextra Foo.hs) yields the following:

Foo.hs:10:1: error:
    • Could not deduce (Foo ())
      from the context: Applicative f
        bound by the inferred type for ‘bar’:
                   forall (f :: * -> *). Applicative f => f ()
        at Foo.hs:10:1-14
    • When checking that the inferred type
        bar :: forall (f :: * -> *). (Foo (), Applicative f) => f ()
      is as general as its (partial) signature
        bar :: forall (f :: * -> *). Applicative f => f ()
   |
10 | bar = pure foo
   | ^^^^^^^^^^^^^^

Foo.hs:13:12: error:
    • Could not deduce (Foo ()) arising from a use of ‘foo’
      from the context: Applicative f
        bound by the inferred type of baz :: Applicative f => f ()
        at Foo.hs:13:1-14
    • In the first argument of ‘pure’, namely ‘foo’
      In the expression: pure foo
      In an equation for ‘baz’: baz = pure foo
   |
13 | baz = pure foo
   |            ^^^

bar and baz don't typecheck. bob, marie and anne typecheck fine.

Expected behavior

I presume the resolution of PartialTypeSignature wildcards does not account for some kinds of orphan instances.

bar

I am not quite sure what is going on here.

I expect it to work the same way as if _ is substituted for Applicative f:

bar :: (Foo (), Applicative f) => f ()
bar = pure foo

baz

_ appears to not deduce the Foo () constraint.

I suppose this is because one commonly also doesn't require a monomorphic constraint like Ord Int in the type signature. However, in this case there is no Foo () instance in scope (as opposed to Ord Int which is usually in scope).

I expect the constraint to bubble up and be deduced as is the case in anne.

Environment

  • GHC version used:
    • 8.10.1
    • 8.10.2
Edited by Ole
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information