[GHC] #13906: ApplicativeDo doesn't handle existentials as well as it could
GHC
ghc-devs at haskell.org
Fri Jun 30 18:07:53 UTC 2017
#13906: ApplicativeDo doesn't handle existentials as well as it could
-------------------------------------+-------------------------------------
Reporter: dfeuer | Owner: (none)
Type: bug | Status: new
Priority: normal | Milestone: 8.4.1
Component: Compiler | Version: 8.0.1
Keywords: ApplicativeDo | Operating System: Unknown/Multiple
Architecture: | Type of failure: GHC rejects
Unknown/Multiple | valid program
Test Case: | Blocked By:
Blocking: | Related Tickets:
Differential Rev(s): | Wiki Page:
-------------------------------------+-------------------------------------
`ApplicativeDo` doesn't work nicely with existentials or GADTs. This was
first considered in #13242, but I think it's worth reconsidering in light
of #13875. In particular, we no longer need to think specially about
whether a particular pattern match reveals evidence, as any pattern match
that does so must necessarily be strict. Simon Marlow explains (in
revised, I-think-unmerged, documentation) that
{{{#!hs
data T where A :: forall a . Eq a => a -> T
test = do
A x <- undefined
_ <- return 'a'
_ <- return 'b'
return (x == x)
}}}
will not typecheck because it is first rearranged to
{{{#!hs
test =
(\x _ -> x == x)
<$> do A x <- undefined; _ <- return 'a'; return x
<*> return 'b'
}}}
This is weird! The more human-obvious rearrangement would work just fine:
{{{#!hs
test = do
A x <- undefined
(\_ _ -> x == x) <$> return 'a' <*> return 'b'
}}}
How can we get there? I think it's actually easy. Suppose we have
{{{#!hs
do
p1 <- e1
p2 <- e2
p3 <- e3
p4 <- e4
p5 <- e5
e6
}}}
Before starting the detailed dependency analysis and such, let's look just
at ''which patterns are strict''. If a pattern is strict, then ''every''
following action must be seen as depending on it, and therefore its
bindings and evidence can scope over everything else. Let's say that `p3`
is strict. Then we can immediately transform the expression to
{{{#!hs
do
p1 <- e1
p2 <- e2
e3 >>= \case
p3 -> do
p4 <- e4
p5 <- e5
e6
-- if refutable
_ -> fail ...
}}}
and then continue the process in the inner `do` block.
If this is done as an initial pass, then further rearrangement doesn't
need to consider the possibility of strict patterns; there won't be any.
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/13906>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list