diff options
author | Roland Senn <rsx@bluewin.ch> | 2020-02-12 12:42:25 +0100 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-03-02 17:13:55 -0500 |
commit | 7c0c76fb1a11532076a0342655a9c889a2a12768 (patch) | |
tree | 427ba3dbf68ceec39f4fbaf95375ee66739d1d4a /testsuite/tests | |
parent | dbea7e9d4d4a8812f3dbeed720fb6aa97e16f896 (diff) | |
download | haskell-7c0c76fb1a11532076a0342655a9c889a2a12768.tar.gz |
Set `ImpredicativeTypes` during :print command. (#14828)
If ImpredicativeTypes is not enabled, then `:print <term>` will fail if the
type of <term> has nested `forall`s or `=>`s.
This is because the GHCi debugger's internals will attempt to unify a
metavariable with the type of <term> and then display the result, but if the
type has nested `forall`s or `=>`s, then unification will fail.
As a result, `:print` will bail out and the unhelpful result will be
`<term> = (_t1::t1)` (where `t1` is a metavariable).
Beware: <term> can have nested `forall`s even if its definition doesn't use
RankNTypes! Here is an example from #14828:
class Functor f where
fmap :: (a -> b) -> f a -> f b
Somewhat surprisingly, `:print fmap` considers the type of fmap to have
nested foralls. This is because the GHCi debugger sees the type
`fmap :: forall f. Functor f => forall a b. (a -> b) -> f a -> f b`.
We could envision deeply instantiating this type to get the type
`forall f a b. Functor f => (a -> b) -> f a -> f b`,
but this trick wouldn't work for higher-rank types.
Instead, we adopt a simpler fix: enable `ImpredicativeTypes` when using
`:print` and friends in the GHCi debugger. This is allows metavariables
to unify with types that have nested (or higher-rank) `forall`s/`=>`s,
which makes `:print fmap` display as
`fmap = (_t1::forall a b. Functor f => (a -> b) -> f a -> f b)`, as expected.
Although ImpredicativeTypes is a somewhat unpredictable from a type inference
perspective, there is no danger in using it in the GHCi debugger, since all
of the terms that the GHCi debugger deals with have already been typechecked.
Diffstat (limited to 'testsuite/tests')
-rw-r--r-- | testsuite/tests/ghci.debugger/scripts/print027.stdout | 12 | ||||
-rw-r--r-- | testsuite/tests/ghci/scripts/T14828.stdout | 20 |
2 files changed, 18 insertions, 14 deletions
diff --git a/testsuite/tests/ghci.debugger/scripts/print027.stdout b/testsuite/tests/ghci.debugger/scripts/print027.stdout index eb5b363693..3117eace87 100644 --- a/testsuite/tests/ghci.debugger/scripts/print027.stdout +++ b/testsuite/tests/ghci.debugger/scripts/print027.stdout @@ -1,6 +1,6 @@ -+ = (_t1::t1) -print = (_t2::t1) -log = (_t3::t1) -head = (_t4::[a] -> a) -tail = (_t5::[a1] -> [a1]) -fst = (_t6::(a2, b) -> a2) ++ = (_t1::Num a => a -> a -> a) +print = (_t2::Show a1 => a1 -> IO ()) +log = (_t3::Floating a2 => a2 -> a2) +head = (_t4::[a4] -> a4) +tail = (_t5::[a7] -> [a7]) +fst = (_t6::(a11, b) -> a11) diff --git a/testsuite/tests/ghci/scripts/T14828.stdout b/testsuite/tests/ghci/scripts/T14828.stdout index 9ccea0ceec..501f8004d5 100644 --- a/testsuite/tests/ghci/scripts/T14828.stdout +++ b/testsuite/tests/ghci/scripts/T14828.stdout @@ -1,12 +1,16 @@ foldl :: Foldable t => (b -> a -> b) -> b -> t a -> b -foldl = (_t1::t1) +foldl = (_t1::forall b a. + Foldable t => + (b -> a -> b) -> b -> t a -> b) fmap :: Functor f => (a -> b) -> f a -> f b -fmap = (_t2::t1) +fmap = (_t2::forall a b. Functor f => (a -> b) -> f a -> f b) return :: Monad m => a -> m a -return = (_t3::t1) +return = (_t3::forall a. Monad m => a -> m a) pure :: Applicative f => a -> f a -pure = (_t4::t1) -mempty = (_t5::t1) -mappend = (_t6::t1) -foldl' = (_t7::t1) -f = (_t8::t1) +pure = (_t4::forall a. Applicative f1 => a -> f1 a) +mempty = (_t5::Monoid a => a) +mappend = (_t6::Monoid a => a -> a -> a) +foldl' = (_t7::forall b a. + Foldable t => + (b -> a -> b) -> b -> t a -> b) +f = (_t8::(forall a. a -> a) -> b -> b) |