Defer ambiguous types check
With the introduction of TypeApplications, functions previously using the Proxy trick can be rewritten without Proxies, opting instead to be called with a type application. However, it seems like the AllowAmbiguousTypes check is too strict, and it would be nice to make the check lazier.
One minor inconvenience this problem creates is in GHCi:
>>> :set -XAllowAmbiguousTypes >>> class Foo a where foo :: String >>> :t foo No instance for (Foo a0) arising from a use of 'foo'
It would be nice to display the type of
Foo a => String.
More notably, the following problem doesn't compile:
class HasLabel x where getLabel :: String instance HasLabel Int where getLabel = "I am an Int!" runFunc :: forall f y a. f y => (forall x. f x => a) -> a runFunc f = f @y main :: IO () main = putStrLn $ runFunc @HasLabel @Int getLabel
Foo.hs:17:42: error: • Could not deduce (HasLabel x0) arising from a use of ‘getLabel’ from the context: HasLabel x bound by a type expected by the context: forall x. HasLabel x => String at Foo.hs:17:42-49 The type variable ‘x0’ is ambiguous These potential instance exist: instance HasLabel Int -- Defined at Foo.hs:10:10 • In the third argument of ‘runFunc’, namely ‘getLabel’ In the second argument of ‘($)’, namely ‘runFunc @HasLabel @Int getLabel’ In the expression: putStrLn $ runFunc @HasLabel @Int getLabel | 17 | main = putStrLn $ runFunc @HasLabel @Int getLabel | ^^^^^^^^
It would be nice for
getLabel to keep its
HasLabel x => String type until it's actually called in
runFunc with type applications.
As a final note, I'm not too familiar with how type checking works (e.g. Hindley-Milner type inference), so I'm not sure if this is possible. Just figured it'd be worth it to bring up, just in case.
For a type class
class Foo a where bar :: ...
:t bar should work in GHCi, whether or not
a is referenced in the type signature of
bar. More generally,
bar should be treated as the type
forall a. Foo a => ... and can be passed into higher-order functions.