Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
cbe4300e
by Simon Peyton Jones at 2026-02-05T04:31:04-05:00
-
a193a8da
by Simon Peyton Jones at 2026-02-05T04:31:04-05:00
-
b579dfdc
by Simon Peyton Jones at 2026-02-05T04:31:04-05:00
9 changed files:
- compiler/GHC/Core/Opt/Simplify/Iteration.hs
- compiler/GHC/Core/Opt/Simplify/Utils.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Types/Evidence.hs
- testsuite/tests/ghci.debugger/scripts/T26042b.stdout
- testsuite/tests/ghci.debugger/scripts/T26042c.stdout
- testsuite/tests/ghci.debugger/scripts/T26042d2.stdout
- testsuite/tests/ghci.debugger/scripts/T26042f2.stdout
Changes:
| ... | ... | @@ -1713,6 +1713,7 @@ simplCast env body co0 cont0 |
| 1713 | 1713 | , sc_hole_ty = coercionLKind co }) }
|
| 1714 | 1714 | -- NB! As the cast goes past, the
|
| 1715 | 1715 | -- type of the hole changes (#16312)
|
| 1716 | + |
|
| 1716 | 1717 | -- (f |> co) e ===> (f (e |> co1)) |> co2
|
| 1717 | 1718 | -- where co :: (s1->s2) ~ (t1->t2)
|
| 1718 | 1719 | -- co1 :: t1 ~ s1
|
| ... | ... | @@ -1838,7 +1839,7 @@ simpl_lam env bndr body (ApplyToVal { sc_arg = arg, sc_env = arg_se |
| 1838 | 1839 | , not ( isSimplified dup && -- See (SR2) in Note [Avoiding simplifying repeatedly]
|
| 1839 | 1840 | not (exprIsTrivial arg) &&
|
| 1840 | 1841 | not (isDeadOcc (idOccInfo bndr)) )
|
| 1841 | - -> do { simplTrace "SimplBindr:inline-uncond3" (ppr bndr) $
|
|
| 1842 | + -> do { simplTrace "SimplBindr:inline-uncond3" (ppr bndr <+> text ":=" <+> ppr arg $$ ppr (seIdSubst env)) $
|
|
| 1842 | 1843 | tick (PreInlineUnconditionally bndr)
|
| 1843 | 1844 | ; simplLam env' body cont }
|
| 1844 | 1845 |
| ... | ... | @@ -72,6 +72,7 @@ import GHC.Types.Tickish |
| 72 | 72 | import GHC.Types.Demand
|
| 73 | 73 | import GHC.Types.Var.Set
|
| 74 | 74 | import GHC.Types.Basic
|
| 75 | +import GHC.Types.Name.Env
|
|
| 75 | 76 | |
| 76 | 77 | import GHC.Data.OrdList ( isNilOL )
|
| 77 | 78 | import GHC.Data.FastString ( fsLit )
|
| ... | ... | @@ -81,9 +82,9 @@ import GHC.Utils.Monad |
| 81 | 82 | import GHC.Utils.Outputable
|
| 82 | 83 | import GHC.Utils.Panic
|
| 83 | 84 | |
| 84 | -import Control.Monad ( when )
|
|
| 85 | +import Control.Monad ( guard, when )
|
|
| 85 | 86 | import Data.List ( sortBy )
|
| 86 | -import GHC.Types.Name.Env
|
|
| 87 | +import Data.Maybe
|
|
| 87 | 88 | import Data.Graph
|
| 88 | 89 | |
| 89 | 90 | {- *********************************************************************
|
| ... | ... | @@ -2570,7 +2571,27 @@ Note [Eliminate Identity Case] |
| 2570 | 2571 | True -> True;
|
| 2571 | 2572 | False -> False
|
| 2572 | 2573 | |
| 2573 | -and similar friends.
|
|
| 2574 | +and similar friends. There are some tricky wrinkles:
|
|
| 2575 | + |
|
| 2576 | +(EIC1) Casts. We've seen this:
|
|
| 2577 | + case e of x { _ -> x `cast` c }
|
|
| 2578 | + And we definitely want to eliminate this case, to give
|
|
| 2579 | + e `cast` c
|
|
| 2580 | +(EIC2) Ticks. Similarly
|
|
| 2581 | + case e of x { _ -> Tick t x }
|
|
| 2582 | + At least if the tick is 'floatable' we want to eliminate the case
|
|
| 2583 | + to give
|
|
| 2584 | + Tick t e
|
|
| 2585 | + |
|
| 2586 | +So `check_eq` strips off enclosing casts and ticks from the RHS of the
|
|
| 2587 | +alternative, returning a wrapper function that will rebuild them around
|
|
| 2588 | +the scrutinee if case-elim is successful.
|
|
| 2589 | + |
|
| 2590 | +(EIC3) What if there are many alternatives, all identities. If casts
|
|
| 2591 | + are involved they must be the same cast, to make the types line up.
|
|
| 2592 | + In principle there could be different ticks in each RHS, but we just
|
|
| 2593 | + pick the ticks from the first alternative. (In the common case there
|
|
| 2594 | + is only one alternative.)
|
|
| 2574 | 2595 | |
| 2575 | 2596 | Note [Scrutinee Constant Folding]
|
| 2576 | 2597 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -2764,45 +2785,47 @@ mkCase mode scrut outer_bndr alts_ty alts |
| 2764 | 2785 | -- See Note [Eliminate Identity Case]
|
| 2765 | 2786 | --------------------------------------------------
|
| 2766 | 2787 | |
| 2767 | -mkCase1 _mode scrut case_bndr _ alts@(Alt _ _ rhs1 : alts') -- Identity case
|
|
| 2768 | - | all identity_alt alts
|
|
| 2788 | +mkCase1 _mode scrut case_bndr _ (alt1 : alts) -- Identity case
|
|
| 2789 | + | Just wrap <- identity_alt alt1 -- `wrap`: see (EIC1) and (EIC2)
|
|
| 2790 | + , all (isJust . identity_alt) alts -- See (EIC3) in Note [Eliminate Identity Case]
|
|
| 2769 | 2791 | = do { tick (CaseIdentity case_bndr)
|
| 2770 | - ; return (mkTicks ticks $ re_cast scrut rhs1) }
|
|
| 2792 | + ; return (wrap scrut) }
|
|
| 2771 | 2793 | where
|
| 2772 | - ticks = concatMap (\(Alt _ _ rhs) -> stripTicksT tickishFloatable rhs) alts'
|
|
| 2773 | - identity_alt (Alt con args rhs) = check_eq rhs con args
|
|
| 2774 | - |
|
| 2775 | - check_eq (Cast rhs co) con args -- See Note [RHS casts]
|
|
| 2776 | - = not (any (`elemVarSet` tyCoVarsOfCo co) args) && check_eq rhs con args
|
|
| 2777 | - check_eq (Tick t e) alt args
|
|
| 2778 | - = tickishFloatable t && check_eq e alt args
|
|
| 2779 | - |
|
| 2780 | - check_eq (Lit lit) (LitAlt lit') _ = lit == lit'
|
|
| 2781 | - check_eq (Var v) _ _ | v == case_bndr = True
|
|
| 2782 | - check_eq (Var v) (DataAlt con) args
|
|
| 2783 | - | null arg_tys, null args = v == dataConWorkId con
|
|
| 2784 | - -- Optimisation only
|
|
| 2785 | - check_eq rhs (DataAlt con) args = cheapEqExpr' tickishFloatable rhs $
|
|
| 2786 | - mkConApp2 con arg_tys args
|
|
| 2787 | - check_eq _ _ _ = False
|
|
| 2794 | + identity_alt :: CoreAlt -> Maybe (CoreExpr -> CoreExpr)
|
|
| 2795 | + identity_alt (Alt con args rhs) = check_eq con args rhs
|
|
| 2796 | + |
|
| 2797 | + check_eq :: AltCon -> [Var] -> CoreExpr -> Maybe (CoreExpr -> CoreExpr)
|
|
| 2798 | + -- (check_eq con args e) return True if
|
|
| 2799 | + -- e looks like (Tick (Cast (Tick (con args))))
|
|
| 2800 | + -- where (con args) is the LHS of the alternative
|
|
| 2801 | + -- In that case it returns (\e. Tick (Cast (Tick e))),
|
|
| 2802 | + -- a wrapper function that can rebuild the tick/cast stuff
|
|
| 2803 | + -- See (EIC1) and (EIC2) in Note [Eliminate Identity Case]
|
|
| 2804 | + check_eq alt_con args (Cast e co) -- See (EIC1)
|
|
| 2805 | + = do { guard (not (any (`elemVarSet` tyCoVarsOfCo co) args))
|
|
| 2806 | + ; wrap <- check_eq alt_con args e
|
|
| 2807 | + ; return (flip mkCast co . wrap) }
|
|
| 2808 | + check_eq alt_con args (Tick t e) -- See (EIC2)
|
|
| 2809 | + = do { guard (tickishFloatable t)
|
|
| 2810 | + ; wrap <- check_eq alt_con args e
|
|
| 2811 | + ; return (Tick t . wrap) }
|
|
| 2812 | + check_eq alt_con args e
|
|
| 2813 | + | is_id alt_con args e = Just (\e -> e)
|
|
| 2814 | + | otherwise = Nothing
|
|
| 2815 | + |
|
| 2816 | + is_id :: AltCon -> [Var] -> CoreExpr -> Bool
|
|
| 2817 | + is_id _ _ (Var v) | v == case_bndr = True
|
|
| 2818 | + is_id (LitAlt lit') _ (Lit lit) = lit == lit'
|
|
| 2819 | + is_id (DataAlt con) args rhs
|
|
| 2820 | + | Var v <- rhs -- Optimisation only
|
|
| 2821 | + , null arg_tys
|
|
| 2822 | + , null args = v == dataConWorkId con
|
|
| 2823 | + | otherwise = cheapEqExpr' tickishFloatable rhs $
|
|
| 2824 | + mkConApp2 con arg_tys args
|
|
| 2825 | + is_id _ _ _ = False
|
|
| 2788 | 2826 | |
| 2789 | 2827 | arg_tys = tyConAppArgs (idType case_bndr)
|
| 2790 | 2828 | |
| 2791 | - -- Note [RHS casts]
|
|
| 2792 | - -- ~~~~~~~~~~~~~~~~
|
|
| 2793 | - -- We've seen this:
|
|
| 2794 | - -- case e of x { _ -> x `cast` c }
|
|
| 2795 | - -- And we definitely want to eliminate this case, to give
|
|
| 2796 | - -- e `cast` c
|
|
| 2797 | - -- So we throw away the cast from the RHS, and reconstruct
|
|
| 2798 | - -- it at the other end. All the RHS casts must be the same
|
|
| 2799 | - -- if (all identity_alt alts) holds.
|
|
| 2800 | - --
|
|
| 2801 | - -- Don't worry about nested casts, because the simplifier combines them
|
|
| 2802 | - |
|
| 2803 | - re_cast scrut (Cast rhs co) = Cast (re_cast scrut rhs) co
|
|
| 2804 | - re_cast scrut _ = scrut
|
|
| 2805 | - |
|
| 2806 | 2829 | mkCase1 mode scrut bndr alts_ty alts = mkCase2 mode scrut bndr alts_ty alts
|
| 2807 | 2830 | |
| 2808 | 2831 |
| ... | ... | @@ -252,7 +252,7 @@ applyTypeToArgs op_ty args |
| 252 | 252 | |
| 253 | 253 | mkCastMCo :: CoreExpr -> MCoercionR -> CoreExpr
|
| 254 | 254 | mkCastMCo e MRefl = e
|
| 255 | -mkCastMCo e (MCo co) = Cast e co
|
|
| 255 | +mkCastMCo e (MCo co) = mkCast e co
|
|
| 256 | 256 | -- We are careful to use (MCo co) only when co is not reflexive
|
| 257 | 257 | -- Hence (Cast e co) rather than (mkCast e co)
|
| 258 | 258 | |
| ... | ... | @@ -305,40 +305,41 @@ mkCast expr co |
| 305 | 305 | -- | Wraps the given expression in the source annotation, dropping the
|
| 306 | 306 | -- annotation if possible.
|
| 307 | 307 | mkTick :: CoreTickish -> CoreExpr -> CoreExpr
|
| 308 | -mkTick t orig_expr = mkTick' id id orig_expr
|
|
| 308 | +mkTick t orig_expr = mkTick' id orig_expr
|
|
| 309 | 309 | where
|
| 310 | 310 | -- Some ticks (cost-centres) can be split in two, with the
|
| 311 | 311 | -- non-counting part having laxer placement properties.
|
| 312 | 312 | canSplit = tickishCanSplit t && tickishPlace (mkNoCount t) /= tickishPlace t
|
| 313 | + |
|
| 313 | 314 | -- mkTick' handles floating of ticks *into* the expression.
|
| 314 | - -- In this function, `top` is applied after adding the tick, and `rest` before.
|
|
| 315 | - -- This will result in applications that look like (top $ Tick t $ rest expr).
|
|
| 316 | - -- If we want to push the tick deeper, we pre-compose `top` with a function
|
|
| 317 | - -- adding the tick.
|
|
| 318 | - mkTick' :: (CoreExpr -> CoreExpr) -- apply after adding tick (float through)
|
|
| 319 | - -> (CoreExpr -> CoreExpr) -- apply before adding tick (float with)
|
|
| 320 | - -> CoreExpr -- current expression
|
|
| 315 | + mkTick' :: (CoreExpr -> CoreExpr) -- Apply before adding tick (float with)
|
|
| 316 | + -- Always a composition of (Tick t) wrappers
|
|
| 317 | + -> CoreExpr -- Current expression
|
|
| 321 | 318 | -> CoreExpr
|
| 322 | - mkTick' top rest expr = case expr of
|
|
| 319 | + -- So in the call (mkTick' rest e), the expression
|
|
| 320 | + -- (rest e)
|
|
| 321 | + -- has the same type as e
|
|
| 322 | + -- Returns an expression equivalent to (Tick t (rest e))
|
|
| 323 | + mkTick' rest expr = case expr of
|
|
| 323 | 324 | -- Float ticks into unsafe coerce the same way we would do with a cast.
|
| 324 | 325 | Case scrut bndr ty alts@[Alt ac abs _rhs]
|
| 325 | 326 | | Just rhs <- isUnsafeEqualityCase scrut bndr alts
|
| 326 | - -> top $ mkTick' (\e -> Case scrut bndr ty [Alt ac abs e]) rest rhs
|
|
| 327 | + -> Case scrut bndr ty [Alt ac abs (mkTick' rest rhs)]
|
|
| 327 | 328 | |
| 328 | 329 | -- Cost centre ticks should never be reordered relative to each
|
| 329 | 330 | -- other. Therefore we can stop whenever two collide.
|
| 330 | 331 | Tick t2 e
|
| 331 | - | ProfNote{} <- t2, ProfNote{} <- t -> top $ Tick t $ rest expr
|
|
| 332 | + | ProfNote{} <- t2, ProfNote{} <- t -> Tick t $ rest expr
|
|
| 332 | 333 | |
| 333 | 334 | -- Otherwise we assume that ticks of different placements float
|
| 334 | 335 | -- through each other.
|
| 335 | - | tickishPlace t2 /= tickishPlace t -> mkTick' (top . Tick t2) rest e
|
|
| 336 | + | tickishPlace t2 /= tickishPlace t -> Tick t2 $ mkTick' rest e
|
|
| 336 | 337 | |
| 337 | 338 | -- For annotations this is where we make sure to not introduce
|
| 338 | 339 | -- redundant ticks.
|
| 339 | - | tickishContains t t2 -> mkTick' top rest e
|
|
| 340 | - | tickishContains t2 t -> orig_expr
|
|
| 341 | - | otherwise -> mkTick' top (rest . Tick t2) e
|
|
| 340 | + | tickishContains t t2 -> mkTick' rest e -- Drop t2
|
|
| 341 | + | tickishContains t2 t -> rest e -- Drop t
|
|
| 342 | + | otherwise -> mkTick' (rest . Tick t2) e
|
|
| 342 | 343 | |
| 343 | 344 | -- Ticks don't care about types, so we just float all ticks
|
| 344 | 345 | -- through them. Note that it's not enough to check for these
|
| ... | ... | @@ -346,14 +347,14 @@ mkTick t orig_expr = mkTick' id id orig_expr |
| 346 | 347 | -- expressions below ticks, such constructs can be the result of
|
| 347 | 348 | -- unfoldings. We therefore make an effort to put everything into
|
| 348 | 349 | -- the right place no matter what we start with.
|
| 349 | - Cast e co -> mkTick' (top . flip Cast co) rest e
|
|
| 350 | - Coercion co -> Coercion co
|
|
| 350 | + Cast e co -> mkCast (mkTick' rest e) co
|
|
| 351 | + Coercion co -> Tick t $ rest (Coercion co)
|
|
| 351 | 352 | |
| 352 | 353 | Lam x e
|
| 353 | 354 | -- Always float through type lambdas. Even for non-type lambdas,
|
| 354 | 355 | -- floating is allowed for all but the most strict placement rule.
|
| 355 | 356 | | not (isRuntimeVar x) || tickishPlace t /= PlaceRuntime
|
| 356 | - -> mkTick' (top . Lam x) rest e
|
|
| 357 | + -> Lam x $ mkTick' rest e
|
|
| 357 | 358 | |
| 358 | 359 | -- If it is both counting and scoped, we split the tick into its
|
| 359 | 360 | -- two components, often allowing us to keep the counting tick on
|
| ... | ... | @@ -362,25 +363,25 @@ mkTick t orig_expr = mkTick' id id orig_expr |
| 362 | 363 | -- floated, and the lambda may then be in a position to be
|
| 363 | 364 | -- beta-reduced.
|
| 364 | 365 | | canSplit
|
| 365 | - -> top $ Tick (mkNoScope t) $ rest $ Lam x $ mkTick (mkNoCount t) e
|
|
| 366 | + -> Tick (mkNoScope t) $ rest $ Lam x $ mkTick (mkNoCount t) e
|
|
| 366 | 367 | |
| 367 | 368 | App f arg
|
| 368 | 369 | -- Always float through type applications.
|
| 369 | 370 | | not (isRuntimeArg arg)
|
| 370 | - -> mkTick' (top . flip App arg) rest f
|
|
| 371 | + -> App (mkTick' rest f) arg
|
|
| 371 | 372 | |
| 372 | 373 | -- We can also float through constructor applications, placement
|
| 373 | 374 | -- permitting. Again we can split.
|
| 374 | 375 | | isSaturatedConApp expr && (tickishPlace t==PlaceCostCentre || canSplit)
|
| 375 | 376 | -> if tickishPlace t == PlaceCostCentre
|
| 376 | - then top $ rest $ tickHNFArgs t expr
|
|
| 377 | - else top $ Tick (mkNoScope t) $ rest $ tickHNFArgs (mkNoCount t) expr
|
|
| 377 | + then rest $ tickHNFArgs t expr
|
|
| 378 | + else Tick (mkNoScope t) $ rest $ tickHNFArgs (mkNoCount t) expr
|
|
| 378 | 379 | |
| 379 | 380 | Var x
|
| 380 | 381 | | notFunction && tickishPlace t == PlaceCostCentre
|
| 381 | - -> orig_expr
|
|
| 382 | + -> rest expr -- Drop t
|
|
| 382 | 383 | | notFunction && canSplit
|
| 383 | - -> top $ Tick (mkNoScope t) $ rest expr
|
|
| 384 | + -> Tick (mkNoScope t) $ rest expr
|
|
| 384 | 385 | where
|
| 385 | 386 | -- SCCs can be eliminated on variables provided the variable
|
| 386 | 387 | -- is not a function. In these cases the SCC makes no difference:
|
| ... | ... | @@ -392,10 +393,10 @@ mkTick t orig_expr = mkTick' id id orig_expr |
| 392 | 393 | |
| 393 | 394 | Lit{}
|
| 394 | 395 | | tickishPlace t == PlaceCostCentre
|
| 395 | - -> orig_expr
|
|
| 396 | + -> rest expr -- Drop t
|
|
| 396 | 397 | |
| 397 | 398 | -- Catch-all: Annotate where we stand
|
| 398 | - _any -> top $ Tick t $ rest expr
|
|
| 399 | + _any -> Tick t $ rest expr
|
|
| 399 | 400 | |
| 400 | 401 | mkTicks :: [CoreTickish] -> CoreExpr -> CoreExpr
|
| 401 | 402 | mkTicks ticks expr = foldr mkTick expr ticks
|
| ... | ... | @@ -49,6 +49,7 @@ import GHC.Core.Make ( mkCharExpr, mkNaturalExpr, mkStringExprFS, mkCoreLams ) |
| 49 | 49 | import GHC.Core.DataCon
|
| 50 | 50 | import GHC.Core.TyCon
|
| 51 | 51 | import GHC.Core.Class
|
| 52 | +import GHC.Core.Utils( mkCast )
|
|
| 52 | 53 | import GHC.Core ( Expr(..), mkConApp )
|
| 53 | 54 | |
| 54 | 55 | import GHC.StgToCmm.Closure ( isSmallFamily )
|
| ... | ... | @@ -455,7 +456,7 @@ matchWithDict [cls_ty, mty] |
| 455 | 456 | = mkCoreLams [ runtimeRep1TyVar, openAlphaTyVar, sv, k ] $
|
| 456 | 457 | Var k `App` (evUnaryDictAppE cls dict_args meth_arg)
|
| 457 | 458 | where
|
| 458 | - meth_arg = Var sv `Cast` mkSubCo (evExprCoercion ev_expr)
|
|
| 459 | + meth_arg = Var sv `mkCast` mkSubCo (evExprCoercion ev_expr)
|
|
| 459 | 460 | |
| 460 | 461 | ; let mk_ev [c] = evDictApp wd_cls [cls_ty, mty] [evWithDict c]
|
| 461 | 462 | mk_ev e = pprPanic "matchWithDict" (ppr e)
|
| ... | ... | @@ -657,7 +658,7 @@ matchDataToTag dataToTagClass [levity, dty] = do |
| 657 | 658 | (mkReflCo Representational intPrimTy)
|
| 658 | 659 | -> do { addUsedDataCons rdr_env repTyCon -- See wrinkles DTW2 and DTW3
|
| 659 | 660 | ; let mk_ev _ = evDictApp dataToTagClass [levity, dty] $
|
| 660 | - [methodRep `Cast` methodCo]
|
|
| 661 | + [methodRep `mkCast` methodCo]
|
|
| 661 | 662 | ; pure (OneInst { cir_new_theta = [] -- (Ignore stupid theta.)
|
| 662 | 663 | , cir_mk_ev = mk_ev
|
| 663 | 664 | , cir_canonical = EvCanonical
|
| ... | ... | @@ -59,6 +59,7 @@ import GHC.Tc.Utils.TcType |
| 59 | 59 | import GHC.Core
|
| 60 | 60 | import GHC.Core.Coercion.Axiom
|
| 61 | 61 | import GHC.Core.Coercion
|
| 62 | +import GHC.Core.Utils( mkCast )
|
|
| 62 | 63 | import GHC.Core.Ppr () -- Instance OutputableBndr TyVar
|
| 63 | 64 | import GHC.Core.Predicate
|
| 64 | 65 | import GHC.Core.Type
|
| ... | ... | @@ -930,7 +931,7 @@ evCastE ee co |
| 930 | 931 | | assertPpr (coercionRole co == Representational)
|
| 931 | 932 | (vcat [text "Coercion of wrong role passed to evCastE:", ppr ee, ppr co]) $
|
| 932 | 933 | isReflCo co = ee
|
| 933 | - | otherwise = Cast ee co
|
|
| 934 | + | otherwise = mkCast ee co
|
|
| 934 | 935 | |
| 935 | 936 | evDFunApp :: DFunId -> [Type] -> [EvExpr] -> EvTerm
|
| 936 | 937 | -- Dictionary instance application, including when the "dictionary function"
|
| ... | ... | @@ -22,30 +22,18 @@ _result :: |
| 22 | 22 | -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
|
| 23 | 23 | Int #) = _
|
| 24 | 24 | Stopped in Main.foo, T26042b.hs:14:3-18
|
| 25 | -_result ::
|
|
| 26 | - GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
|
|
| 27 | - -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
|
|
| 28 | - Int #) = _
|
|
| 25 | +_result :: IO Int = _
|
|
| 29 | 26 | 13 y = 4
|
| 30 | 27 | 14 n <- bar (x + y)
|
| 31 | 28 | ^^^^^^^^^^^^^^^^
|
| 32 | 29 | 15 return n
|
| 33 | -_result ::
|
|
| 34 | - GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
|
|
| 35 | - -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
|
|
| 36 | - Int #) = _
|
|
| 30 | +_result :: IO Int = _
|
|
| 37 | 31 | Stopped in Main.main, T26042b.hs:5:3-26
|
| 38 | -_result ::
|
|
| 39 | - GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
|
|
| 40 | - -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
|
|
| 41 | - () #) = _
|
|
| 32 | +_result :: IO () = _
|
|
| 42 | 33 | 4 main = do
|
| 43 | 34 | 5 a <- foo False undefined
|
| 44 | 35 | ^^^^^^^^^^^^^^^^^^^^^^^^
|
| 45 | 36 | 6 print a
|
| 46 | -_result ::
|
|
| 47 | - GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
|
|
| 48 | - -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
|
|
| 49 | - () #) = _
|
|
| 37 | +_result :: IO () = _
|
|
| 50 | 38 | 14
|
| 51 | 39 | 14 |
| 1 | 1 | Breakpoint 0 activated at T26042c.hs:10:15-22
|
| 2 | 2 | Stopped in Main.foo, T26042c.hs:10:15-22
|
| 3 | -_result ::
|
|
| 4 | - GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
|
|
| 5 | - -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
|
|
| 6 | - Int #) = _
|
|
| 3 | +_result :: IO Int = _
|
|
| 7 | 4 | 9 foo :: Bool -> Int -> IO Int
|
| 8 | 5 | 10 foo True i = return i
|
| 9 | 6 | ^^^^^^^^
|
| 10 | 7 | 11 foo False _ = do
|
| 11 | 8 | Stopped in Main.main, T26042c.hs:5:3-26
|
| 12 | -_result ::
|
|
| 13 | - GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
|
|
| 14 | - -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
|
|
| 15 | - () #) = _
|
|
| 9 | +_result :: IO () = _
|
|
| 16 | 10 | 4 main = do
|
| 17 | 11 | 5 a <- foo False undefined
|
| 18 | 12 | ^^^^^^^^^^^^^^^^^^^^^^^^
|
| 1 | 1 | Breakpoint 0 activated at T26042d2.hs:11:3-21
|
| 2 | 2 | hello1
|
| 3 | 3 | Stopped in Main.f, T26042d2.hs:11:3-21
|
| 4 | -_result ::
|
|
| 5 | - GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld
|
|
| 6 | - -> (# GHC.Internal.Prim.State# GHC.Internal.Prim.RealWorld,
|
|
| 7 | - () #) = _
|
|
| 4 | +_result :: IO () = _
|
|
| 8 | 5 | 10 f = do
|
| 9 | 6 | 11 putStrLn "hello2.1"
|
| 10 | 7 | ^^^^^^^^^^^^^^^^^^^
|
| 1 | 1 | Breakpoint 0 activated at T26042f.hs:(20,7)-(21,14)
|
| 2 | 2 | Stopped in T8.t, T26042f.hs:(20,7)-(21,14)
|
| 3 | -_result :: Int = _
|
|
| 3 | +_result :: Identity Int = _
|
|
| 4 | 4 | x :: Int = 450
|
| 5 | 5 | 19 t :: Int -> Identity Int
|
| 6 | 6 | vv
|
| ... | ... | @@ -18,12 +18,12 @@ _result :: Identity Int = _ |
| 18 | 18 | ^^^^^^^^^^^^
|
| 19 | 19 | 15 n <- pure (a+a)
|
| 20 | 20 | Stopped in T8.f, T26042f.hs:8:3-14
|
| 21 | -_result :: Identity Int = _
|
|
| 21 | +_result :: Int = _
|
|
| 22 | 22 | x :: Int = 15
|
| 23 | 23 | 7 f x = do
|
| 24 | 24 | 8 b <- g (x*x)
|
| 25 | 25 | ^^^^^^^^^^^^
|
| 26 | 26 | 9 y <- pure (b+b)
|
| 27 | 27 | x :: Int = 15
|
| 28 | -_result :: Identity Int = _
|
|
| 28 | +_result :: Int = _
|
|
| 29 | 29 | 7248 |