Commit 68f72f10 authored by Joachim Breitner's avatar Joachim Breitner
Browse files

Replace INLINEABLE by INLINABLE (#12613)

as the latter is the official, correct spelling, and the former just a
misspelling accepted by GHC.

Also document in the user’s guide that the alternative spelling is
accepted

This commit was brough to you by HIW 2016.
parent d1229353
...@@ -1243,7 +1243,7 @@ expandUnfolding_maybe _ = ...@@ -1243,7 +1243,7 @@ expandUnfolding_maybe _ =
hasStableCoreUnfolding_maybe :: Unfolding -> Maybe Bool hasStableCoreUnfolding_maybe :: Unfolding -> Maybe Bool
-- Just True <=> has stable inlining, very keen to inline (eg. INLINE pragma) -- Just True <=> has stable inlining, very keen to inline (eg. INLINE pragma)
-- Just False <=> has stable inlining, open to inlining it (eg. INLINEABLE pragma) -- Just False <=> has stable inlining, open to inlining it (eg. INLINABLE pragma)
-- Nothing <=> not stable, or cannot inline it anyway -- Nothing <=> not stable, or cannot inline it anyway
hasStableCoreUnfolding_maybe (CoreUnfolding { uf_src = src, uf_guidance = guide }) hasStableCoreUnfolding_maybe (CoreUnfolding { uf_src = src, uf_guidance = guide })
| isStableSource src | isStableSource src
......
...@@ -199,22 +199,22 @@ specUnfolding to specialise its unfolding. Some important points: ...@@ -199,22 +199,22 @@ specUnfolding to specialise its unfolding. Some important points:
* There is a bit of hack for INLINABLE functions: * There is a bit of hack for INLINABLE functions:
f :: Ord a => .... f :: Ord a => ....
f = <big-rhs> f = <big-rhs>
{- INLINEABLE f #-} {- INLINABLE f #-}
Now if we specialise f, should the specialised version still have Now if we specialise f, should the specialised version still have
an INLINEABLE pragma? If it does, we'll capture a specialised copy an INLINABLE pragma? If it does, we'll capture a specialised copy
of <big-rhs> as its unfolding, and that probaby won't inline. But of <big-rhs> as its unfolding, and that probaby won't inline. But
if we don't, the specialised version of <big-rhs> might be small if we don't, the specialised version of <big-rhs> might be small
enough to inline at a call site. This happens with Control.Monad.liftM3, enough to inline at a call site. This happens with Control.Monad.liftM3,
and can cause a lot more allocation as a result (nofib n-body shows this). and can cause a lot more allocation as a result (nofib n-body shows this).
Moreover, keeping the INLINEABLE thing isn't much help, because Moreover, keeping the INLINABLE thing isn't much help, because
the specialised function (probaby) isn't overloaded any more. the specialised function (probaby) isn't overloaded any more.
Conclusion: drop the INLINEALE pragma. In practice what this means is: Conclusion: drop the INLINEALE pragma. In practice what this means is:
if a stable unfolding has UnfoldingGuidance of UnfWhen, if a stable unfolding has UnfoldingGuidance of UnfWhen,
we keep it (so the specialised thing too will always inline) we keep it (so the specialised thing too will always inline)
if a stable unfolding has UnfoldingGuidance of UnfIfGoodArgs if a stable unfolding has UnfoldingGuidance of UnfIfGoodArgs
(which arises from INLINEABLE), we discard it (which arises from INLINABLE), we discard it
-} -}
mkCoreUnfolding :: UnfoldingSource -> Bool -> CoreExpr mkCoreUnfolding :: UnfoldingSource -> Bool -> CoreExpr
......
...@@ -927,7 +927,7 @@ reOrderNodes depth bndr_set weak_fvs (node : nodes) binds ...@@ -927,7 +927,7 @@ reOrderNodes depth bndr_set weak_fvs (node : nodes) binds
-- Note [DFuns should not be loop breakers] -- Note [DFuns should not be loop breakers]
| Just be_very_keen <- hasStableCoreUnfolding_maybe (idUnfolding bndr) | Just be_very_keen <- hasStableCoreUnfolding_maybe (idUnfolding bndr)
= if be_very_keen then 6 -- Note [Loop breakers and INLINE/INLINEABLE pragmas] = if be_very_keen then 6 -- Note [Loop breakers and INLINE/INLINABLE pragmas]
else 3 else 3
-- Data structures are more important than INLINE pragmas -- Data structures are more important than INLINE pragmas
-- so that dictionary/method recursion unravels -- so that dictionary/method recursion unravels
...@@ -1010,18 +1010,18 @@ The RULES stuff means that we can't choose $dm as a loop breaker ...@@ -1010,18 +1010,18 @@ The RULES stuff means that we can't choose $dm as a loop breaker
opInt *and* opBool, and so on. The number of loop breakders is opInt *and* opBool, and so on. The number of loop breakders is
linear in the number of instance declarations. linear in the number of instance declarations.
Note [Loop breakers and INLINE/INLINEABLE pragmas] Note [Loop breakers and INLINE/INLINABLE pragmas]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Avoid choosing a function with an INLINE pramga as the loop breaker! Avoid choosing a function with an INLINE pramga as the loop breaker!
If such a function is mutually-recursive with a non-INLINE thing, If such a function is mutually-recursive with a non-INLINE thing,
then the latter should be the loop-breaker. then the latter should be the loop-breaker.
It's vital to distinguish between INLINE and INLINEABLE (the It's vital to distinguish between INLINE and INLINABLE (the
Bool returned by hasStableCoreUnfolding_maybe). If we start with Bool returned by hasStableCoreUnfolding_maybe). If we start with
Rec { {-# INLINEABLE f #-} Rec { {-# INLINABLE f #-}
f x = ...f... } f x = ...f... }
and then worker/wrapper it through strictness analysis, we'll get and then worker/wrapper it through strictness analysis, we'll get
Rec { {-# INLINEABLE $wf #-} Rec { {-# INLINABLE $wf #-}
$wf p q = let x = (p,q) in ...f... $wf p q = let x = (p,q) in ...f...
{-# INLINE f #-} {-# INLINE f #-}
......
...@@ -2969,7 +2969,7 @@ Note [Setting the new unfolding] ...@@ -2969,7 +2969,7 @@ Note [Setting the new unfolding]
can get into an infinite loop can get into an infinite loop
If there's an stable unfolding on a loop breaker (which happens for If there's an stable unfolding on a loop breaker (which happens for
INLINEABLE), we hang on to the inlining. It's pretty dodgy, but the INLINABLE), we hang on to the inlining. It's pretty dodgy, but the
user did say 'INLINE'. May need to revisit this choice. user did say 'INLINE'. May need to revisit this choice.
************************************************************************ ************************************************************************
......
...@@ -421,7 +421,7 @@ This seeding is done in the binding for seed_calls in specRec. ...@@ -421,7 +421,7 @@ This seeding is done in the binding for seed_calls in specRec.
Actually in case (2), instead of using the calls from the RHS, it Actually in case (2), instead of using the calls from the RHS, it
would be better to specialise in the importing module. We'd need to would be better to specialise in the importing module. We'd need to
add an INLINEABLE pragma to the function, and then it can be add an INLINABLE pragma to the function, and then it can be
specialised in the importing scope, just as is done for type classes specialised in the importing scope, just as is done for type classes
in Specialise.specImports. This remains to be done (#10346). in Specialise.specImports. This remains to be done (#10346).
......
...@@ -624,7 +624,7 @@ for instance, the 'specImports' call in 'specProgram'. ...@@ -624,7 +624,7 @@ for instance, the 'specImports' call in 'specProgram'.
Note [Disabling cross-module specialisation] Note [Disabling cross-module specialisation]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Since GHC 7.10 we have performed specialisation of INLINEABLE bindings living Since GHC 7.10 we have performed specialisation of INLINABLE bindings living
in modules outside of the current module. This can sometimes uncover user code in modules outside of the current module. This can sometimes uncover user code
which explodes in size when aggressively optimized. The which explodes in size when aggressively optimized. The
-fno-cross-module-specialise option was introduced to allow users to being -fno-cross-module-specialise option was introduced to allow users to being
...@@ -725,7 +725,7 @@ specImport dflags this_mod top_env done callers rb fn calls_for_fn ...@@ -725,7 +725,7 @@ specImport dflags this_mod top_env done callers rb fn calls_for_fn
2 (vcat [ text "when specialising" <+> quotes (ppr caller) 2 (vcat [ text "when specialising" <+> quotes (ppr caller)
| caller <- callers]) | caller <- callers])
, ifPprDebug (text "calls:" <+> vcat (map (pprCallInfo fn) calls_for_fn)) , ifPprDebug (text "calls:" <+> vcat (map (pprCallInfo fn) calls_for_fn))
, text "Probable fix: add INLINEABLE pragma on" <+> quotes (ppr fn) ]) , text "Probable fix: add INLINABLE pragma on" <+> quotes (ppr fn) ])
; return ([], []) } ; return ([], []) }
| otherwise | otherwise
...@@ -757,17 +757,17 @@ wantSpecImport dflags unf ...@@ -757,17 +757,17 @@ wantSpecImport dflags unf
-- Specialise even INLINE things; it hasn't inlined yet, -- Specialise even INLINE things; it hasn't inlined yet,
-- so perhaps it never will. Moreover it may have calls -- so perhaps it never will. Moreover it may have calls
-- inside it that we want to specialise -- inside it that we want to specialise
| otherwise -> False -- Stable, not INLINE, hence INLINEABLE | otherwise -> False -- Stable, not INLINE, hence INLINABLE
{- Note [Warning about missed specialisations] {- Note [Warning about missed specialisations]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Suppose Suppose
* In module Lib, you carefully mark a function 'foo' INLINEABLE * In module Lib, you carefully mark a function 'foo' INLINABLE
* Import Lib(foo) into another module M * Import Lib(foo) into another module M
* Call 'foo' at some specialised type in M * Call 'foo' at some specialised type in M
Then you jolly well expect it to be specialised in M. But what if Then you jolly well expect it to be specialised in M. But what if
'foo' calls another function 'Lib.bar'. Then you'd like 'bar' to be 'foo' calls another function 'Lib.bar'. Then you'd like 'bar' to be
specialised too. But if 'bar' is not marked INLINEABLE it may well specialised too. But if 'bar' is not marked INLINABLE it may well
not be specialised. The warning Opt_WarnMissedSpecs warns about this. not be specialised. The warning Opt_WarnMissedSpecs warns about this.
It's more noisy to warning about a missed specialisation opportunity It's more noisy to warning about a missed specialisation opportunity
...@@ -1362,7 +1362,7 @@ complicated Refl coercions with Refl pretty aggressively. ...@@ -1362,7 +1362,7 @@ complicated Refl coercions with Refl pretty aggressively.
Note [Orphans and auto-generated rules] Note [Orphans and auto-generated rules]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When we specialise an INLINEABLE function, or when we have When we specialise an INLINABLE function, or when we have
-fspecialise-aggressively, we auto-generate RULES that are orphans. -fspecialise-aggressively, we auto-generate RULES that are orphans.
We don't want to warn about these, or we'd generate a lot of warnings. We don't want to warn about these, or we'd generate a lot of warnings.
Thus, we only warn about user-specified orphan rules. Thus, we only warn about user-specified orphan rules.
...@@ -1687,7 +1687,7 @@ all they should be inlined, right? Two reasons: ...@@ -1687,7 +1687,7 @@ all they should be inlined, right? Two reasons:
This particular example had a huge effect on the call to replicateM_ This particular example had a huge effect on the call to replicateM_
in nofib/shootout/n-body. in nofib/shootout/n-body.
Why (b): discard INLINEABLE pragmas? See Trac #4874 for persuasive examples. Why (b): discard INLINABLE pragmas? See Trac #4874 for persuasive examples.
Suppose we have Suppose we have
{-# INLINABLE f #-} {-# INLINABLE f #-}
f :: Ord a => [a] -> Int f :: Ord a => [a] -> Int
......
...@@ -12066,6 +12066,8 @@ behaviour: ...@@ -12066,6 +12066,8 @@ behaviour:
recursive function. The principal reason do to so to allow later use recursive function. The principal reason do to so to allow later use
of ``SPECIALISE`` of ``SPECIALISE``
The alternative spelling ``INLINEABLE`` is also accepted by GHC.
.. _noinline-pragma: .. _noinline-pragma:
NOINLINE pragma NOINLINE pragma
......
...@@ -201,12 +201,12 @@ of ``-W(no-)*``. ...@@ -201,12 +201,12 @@ of ``-W(no-)*``.
-Wall-missed-specialisations -Wall-missed-specialisations
Emits a warning if GHC cannot specialise an overloaded function, usually Emits a warning if GHC cannot specialise an overloaded function, usually
because the function needs an ``INLINEABLE`` pragma. The "all" form reports because the function needs an ``INLINABLE`` pragma. The "all" form reports
all such situations whereas the "non-all" form only reports when the all such situations whereas the "non-all" form only reports when the
situation arises during specialisation of an imported function. situation arises during specialisation of an imported function.
The "non-all" form is intended to catch cases where an imported function The "non-all" form is intended to catch cases where an imported function
that is marked as ``INLINEABLE`` (presumably to enable specialisation) cannot that is marked as ``INLINABLE`` (presumably to enable specialisation) cannot
be specialised as it calls other functions that are themselves not specialised. be specialised as it calls other functions that are themselves not specialised.
Note that these warnings will not throw errors if used with :ghc-flag:`-Werror`. Note that these warnings will not throw errors if used with :ghc-flag:`-Werror`.
......
...@@ -162,14 +162,14 @@ Note: 'foldM' is the same as 'foldlM' ...@@ -162,14 +162,14 @@ Note: 'foldM' is the same as 'foldlM'
-} -}
foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b
{-# INLINEABLE foldM #-} {-# INLINABLE foldM #-}
{-# SPECIALISE foldM :: (a -> b -> IO a) -> a -> [b] -> IO a #-} {-# SPECIALISE foldM :: (a -> b -> IO a) -> a -> [b] -> IO a #-}
{-# SPECIALISE foldM :: (a -> b -> Maybe a) -> a -> [b] -> Maybe a #-} {-# SPECIALISE foldM :: (a -> b -> Maybe a) -> a -> [b] -> Maybe a #-}
foldM = foldlM foldM = foldlM
-- | Like 'foldM', but discards the result. -- | Like 'foldM', but discards the result.
foldM_ :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m () foldM_ :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m ()
{-# INLINEABLE foldM_ #-} {-# INLINABLE foldM_ #-}
{-# SPECIALISE foldM_ :: (a -> b -> IO a) -> a -> [b] -> IO () #-} {-# SPECIALISE foldM_ :: (a -> b -> IO a) -> a -> [b] -> IO () #-}
{-# SPECIALISE foldM_ :: (a -> b -> Maybe a) -> a -> [b] -> Maybe () #-} {-# SPECIALISE foldM_ :: (a -> b -> Maybe a) -> a -> [b] -> Maybe () #-}
foldM_ f a xs = foldlM f a xs >> return () foldM_ f a xs = foldlM f a xs >> return ()
...@@ -198,7 +198,7 @@ Core: https://ghc.haskell.org/trac/ghc/ticket/11795#comment:6 ...@@ -198,7 +198,7 @@ Core: https://ghc.haskell.org/trac/ghc/ticket/11795#comment:6
-- | @'replicateM' n act@ performs the action @n@ times, -- | @'replicateM' n act@ performs the action @n@ times,
-- gathering the results. -- gathering the results.
replicateM :: (Applicative m) => Int -> m a -> m [a] replicateM :: (Applicative m) => Int -> m a -> m [a]
{-# INLINEABLE replicateM #-} {-# INLINABLE replicateM #-}
{-# SPECIALISE replicateM :: Int -> IO a -> IO [a] #-} {-# SPECIALISE replicateM :: Int -> IO a -> IO [a] #-}
{-# SPECIALISE replicateM :: Int -> Maybe a -> Maybe [a] #-} {-# SPECIALISE replicateM :: Int -> Maybe a -> Maybe [a] #-}
replicateM cnt0 f = replicateM cnt0 f =
...@@ -210,7 +210,7 @@ replicateM cnt0 f = ...@@ -210,7 +210,7 @@ replicateM cnt0 f =
-- | Like 'replicateM', but discards the result. -- | Like 'replicateM', but discards the result.
replicateM_ :: (Applicative m) => Int -> m a -> m () replicateM_ :: (Applicative m) => Int -> m a -> m ()
{-# INLINEABLE replicateM_ #-} {-# INLINABLE replicateM_ #-}
{-# SPECIALISE replicateM_ :: Int -> IO a -> IO () #-} {-# SPECIALISE replicateM_ :: Int -> IO a -> IO () #-}
{-# SPECIALISE replicateM_ :: Int -> Maybe a -> Maybe () #-} {-# SPECIALISE replicateM_ :: Int -> Maybe a -> Maybe () #-}
replicateM_ cnt0 f = replicateM_ cnt0 f =
...@@ -223,7 +223,7 @@ replicateM_ cnt0 f = ...@@ -223,7 +223,7 @@ replicateM_ cnt0 f =
-- | The reverse of 'when'. -- | The reverse of 'when'.
unless :: (Applicative f) => Bool -> f () -> f () unless :: (Applicative f) => Bool -> f () -> f ()
{-# INLINEABLE unless #-} {-# INLINABLE unless #-}
{-# SPECIALISE unless :: Bool -> IO () -> IO () #-} {-# SPECIALISE unless :: Bool -> IO () -> IO () #-}
{-# SPECIALISE unless :: Bool -> Maybe () -> Maybe () #-} {-# SPECIALISE unless :: Bool -> Maybe () -> Maybe () #-}
unless p s = if p then pure () else s unless p s = if p then pure () else s
...@@ -251,7 +251,7 @@ f <$!> m = do ...@@ -251,7 +251,7 @@ f <$!> m = do
-- @mfilter odd (Just 2) == Nothing@ -- @mfilter odd (Just 2) == Nothing@
mfilter :: (MonadPlus m) => (a -> Bool) -> m a -> m a mfilter :: (MonadPlus m) => (a -> Bool) -> m a -> m a
{-# INLINEABLE mfilter #-} {-# INLINABLE mfilter #-}
mfilter p ma = do mfilter p ma = do
a <- ma a <- ma
if p a then return a else mzero if p a then return a else mzero
......
...@@ -590,7 +590,7 @@ toIntegralSized x -- See Note [toIntegralSized optimization] ...@@ -590,7 +590,7 @@ toIntegralSized x -- See Note [toIntegralSized optimization]
then Just (bit (yW-1)-1) then Just (bit (yW-1)-1)
else Just (bit yW-1) else Just (bit yW-1)
| otherwise = Nothing | otherwise = Nothing
{-# INLINEABLE toIntegralSized #-} {-# INLINABLE toIntegralSized #-}
-- | 'True' if the size of @a@ is @<=@ the size of @b@, where size is measured -- | 'True' if the size of @a@ is @<=@ the size of @b@, where size is measured
-- by 'bitSizeMaybe' and 'isSigned'. -- by 'bitSizeMaybe' and 'isSigned'.
......
...@@ -441,13 +441,13 @@ liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d ...@@ -441,13 +441,13 @@ liftA3 :: Applicative f => (a -> b -> c -> d) -> f a -> f b -> f c -> f d
liftA3 f a b c = fmap f a <*> b <*> c liftA3 f a b c = fmap f a <*> b <*> c
{-# INLINEABLE liftA #-} {-# INLINABLE liftA #-}
{-# SPECIALISE liftA :: (a1->r) -> IO a1 -> IO r #-} {-# SPECIALISE liftA :: (a1->r) -> IO a1 -> IO r #-}
{-# SPECIALISE liftA :: (a1->r) -> Maybe a1 -> Maybe r #-} {-# SPECIALISE liftA :: (a1->r) -> Maybe a1 -> Maybe r #-}
{-# INLINEABLE liftA2 #-} {-# INLINABLE liftA2 #-}
{-# SPECIALISE liftA2 :: (a1->a2->r) -> IO a1 -> IO a2 -> IO r #-} {-# SPECIALISE liftA2 :: (a1->a2->r) -> IO a1 -> IO a2 -> IO r #-}
{-# SPECIALISE liftA2 :: (a1->a2->r) -> Maybe a1 -> Maybe a2 -> Maybe r #-} {-# SPECIALISE liftA2 :: (a1->a2->r) -> Maybe a1 -> Maybe a2 -> Maybe r #-}
{-# INLINEABLE liftA3 #-} {-# INLINABLE liftA3 #-}
{-# SPECIALISE liftA3 :: (a1->a2->a3->r) -> IO a1 -> IO a2 -> IO a3 -> IO r #-} {-# SPECIALISE liftA3 :: (a1->a2->a3->r) -> IO a1 -> IO a2 -> IO a3 -> IO r #-}
{-# SPECIALISE liftA3 :: (a1->a2->a3->r) -> {-# SPECIALISE liftA3 :: (a1->a2->a3->r) ->
Maybe a1 -> Maybe a2 -> Maybe a3 -> Maybe r #-} Maybe a1 -> Maybe a2 -> Maybe a3 -> Maybe r #-}
...@@ -547,7 +547,7 @@ f =<< x = x >>= f ...@@ -547,7 +547,7 @@ f =<< x = x >>= f
-- will output the string @Debugging@ if the Boolean value @debug@ -- will output the string @Debugging@ if the Boolean value @debug@
-- is 'True', and otherwise do nothing. -- is 'True', and otherwise do nothing.
when :: (Applicative f) => Bool -> f () -> f () when :: (Applicative f) => Bool -> f () -> f ()
{-# INLINEABLE when #-} {-# INLINABLE when #-}
{-# SPECIALISE when :: Bool -> IO () -> IO () #-} {-# SPECIALISE when :: Bool -> IO () -> IO () #-}
{-# SPECIALISE when :: Bool -> Maybe () -> Maybe () #-} {-# SPECIALISE when :: Bool -> Maybe () -> Maybe () #-}
when p s = if p then s else pure () when p s = if p then s else pure ()
...@@ -611,19 +611,19 @@ liftM4 f m1 m2 m3 m4 = do { x1 <- m1; x2 <- m2; x3 <- m3; x4 <- m4; return (f ...@@ -611,19 +611,19 @@ liftM4 f m1 m2 m3 m4 = do { x1 <- m1; x2 <- m2; x3 <- m3; x4 <- m4; return (f
liftM5 :: (Monad m) => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r liftM5 :: (Monad m) => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r
liftM5 f m1 m2 m3 m4 m5 = do { x1 <- m1; x2 <- m2; x3 <- m3; x4 <- m4; x5 <- m5; return (f x1 x2 x3 x4 x5) } liftM5 f m1 m2 m3 m4 m5 = do { x1 <- m1; x2 <- m2; x3 <- m3; x4 <- m4; x5 <- m5; return (f x1 x2 x3 x4 x5) }
{-# INLINEABLE liftM #-} {-# INLINABLE liftM #-}
{-# SPECIALISE liftM :: (a1->r) -> IO a1 -> IO r #-} {-# SPECIALISE liftM :: (a1->r) -> IO a1 -> IO r #-}
{-# SPECIALISE liftM :: (a1->r) -> Maybe a1 -> Maybe r #-} {-# SPECIALISE liftM :: (a1->r) -> Maybe a1 -> Maybe r #-}
{-# INLINEABLE liftM2 #-} {-# INLINABLE liftM2 #-}
{-# SPECIALISE liftM2 :: (a1->a2->r) -> IO a1 -> IO a2 -> IO r #-} {-# SPECIALISE liftM2 :: (a1->a2->r) -> IO a1 -> IO a2 -> IO r #-}
{-# SPECIALISE liftM2 :: (a1->a2->r) -> Maybe a1 -> Maybe a2 -> Maybe r #-} {-# SPECIALISE liftM2 :: (a1->a2->r) -> Maybe a1 -> Maybe a2 -> Maybe r #-}
{-# INLINEABLE liftM3 #-} {-# INLINABLE liftM3 #-}
{-# SPECIALISE liftM3 :: (a1->a2->a3->r) -> IO a1 -> IO a2 -> IO a3 -> IO r #-} {-# SPECIALISE liftM3 :: (a1->a2->a3->r) -> IO a1 -> IO a2 -> IO a3 -> IO r #-}
{-# SPECIALISE liftM3 :: (a1->a2->a3->r) -> Maybe a1 -> Maybe a2 -> Maybe a3 -> Maybe r #-} {-# SPECIALISE liftM3 :: (a1->a2->a3->r) -> Maybe a1 -> Maybe a2 -> Maybe a3 -> Maybe r #-}
{-# INLINEABLE liftM4 #-} {-# INLINABLE liftM4 #-}
{-# SPECIALISE liftM4 :: (a1->a2->a3->a4->r) -> IO a1 -> IO a2 -> IO a3 -> IO a4 -> IO r #-} {-# SPECIALISE liftM4 :: (a1->a2->a3->a4->r) -> IO a1 -> IO a2 -> IO a3 -> IO a4 -> IO r #-}
{-# SPECIALISE liftM4 :: (a1->a2->a3->a4->r) -> Maybe a1 -> Maybe a2 -> Maybe a3 -> Maybe a4 -> Maybe r #-} {-# SPECIALISE liftM4 :: (a1->a2->a3->a4->r) -> Maybe a1 -> Maybe a2 -> Maybe a3 -> Maybe a4 -> Maybe r #-}
{-# INLINEABLE liftM5 #-} {-# INLINABLE liftM5 #-}
{-# SPECIALISE liftM5 :: (a1->a2->a3->a4->a5->r) -> IO a1 -> IO a2 -> IO a3 -> IO a4 -> IO a5 -> IO r #-} {-# SPECIALISE liftM5 :: (a1->a2->a3->a4->a5->r) -> IO a1 -> IO a2 -> IO a3 -> IO a4 -> IO a5 -> IO r #-}
{-# SPECIALISE liftM5 :: (a1->a2->a3->a4->a5->r) -> Maybe a1 -> Maybe a2 -> Maybe a3 -> Maybe a4 -> Maybe a5 -> Maybe r #-} {-# SPECIALISE liftM5 :: (a1->a2->a3->a4->a5->r) -> Maybe a1 -> Maybe a2 -> Maybe a3 -> Maybe a4 -> Maybe a5 -> Maybe r #-}
...@@ -642,7 +642,7 @@ ap :: (Monad m) => m (a -> b) -> m a -> m b ...@@ -642,7 +642,7 @@ ap :: (Monad m) => m (a -> b) -> m a -> m b
ap m1 m2 = do { x1 <- m1; x2 <- m2; return (x1 x2) } ap m1 m2 = do { x1 <- m1; x2 <- m2; return (x1 x2) }
-- Since many Applicative instances define (<*>) = ap, we -- Since many Applicative instances define (<*>) = ap, we
-- cannot define ap = (<*>) -- cannot define ap = (<*>)
{-# INLINEABLE ap #-} {-# INLINABLE ap #-}
{-# SPECIALISE ap :: IO (a -> b) -> IO a -> IO b #-} {-# SPECIALISE ap :: IO (a -> b) -> IO a -> IO b #-}
{-# SPECIALISE ap :: Maybe (a -> b) -> Maybe a -> Maybe b #-} {-# SPECIALISE ap :: Maybe (a -> b) -> Maybe a -> Maybe b #-}
......
...@@ -396,7 +396,7 @@ scanr1 f (x:xs) = f x q : qs ...@@ -396,7 +396,7 @@ scanr1 f (x:xs) = f x q : qs
-- It is a special case of 'Data.List.maximumBy', which allows the -- It is a special case of 'Data.List.maximumBy', which allows the
-- programmer to supply their own comparison function. -- programmer to supply their own comparison function.
maximum :: (Ord a) => [a] -> a maximum :: (Ord a) => [a] -> a
{-# INLINEABLE maximum #-} {-# INLINABLE maximum #-}
maximum [] = errorEmptyList "maximum" maximum [] = errorEmptyList "maximum"
maximum xs = foldl1 max xs maximum xs = foldl1 max xs
...@@ -411,7 +411,7 @@ maximum xs = foldl1 max xs ...@@ -411,7 +411,7 @@ maximum xs = foldl1 max xs
-- It is a special case of 'Data.List.minimumBy', which allows the -- It is a special case of 'Data.List.minimumBy', which allows the
-- programmer to supply their own comparison function. -- programmer to supply their own comparison function.
minimum :: (Ord a) => [a] -> a minimum :: (Ord a) => [a] -> a
{-# INLINEABLE minimum #-} {-# INLINABLE minimum #-}
minimum [] = errorEmptyList "minimum" minimum [] = errorEmptyList "minimum"
minimum xs = foldl1 min xs minimum xs = foldl1 min xs
......
...@@ -476,8 +476,8 @@ showSigned showPos p x ...@@ -476,8 +476,8 @@ showSigned showPos p x
even, odd :: (Integral a) => a -> Bool even, odd :: (Integral a) => a -> Bool
even n = n `rem` 2 == 0 even n = n `rem` 2 == 0
odd = not . even odd = not . even
{-# INLINEABLE even #-} {-# INLINABLE even #-}
{-# INLINEABLE odd #-} {-# INLINABLE odd #-}
------------------------------------------------------- -------------------------------------------------------
-- | raise a number to a non-negative integral power -- | raise a number to a non-negative integral power
......
...@@ -615,7 +615,7 @@ test('T6048', ...@@ -615,7 +615,7 @@ test('T6048',
# prev: 38000000 (x86/Linux) # prev: 38000000 (x86/Linux)
# 2012-10-08: 48887164 (x86/Linux) # 2012-10-08: 48887164 (x86/Linux)
# 2014-04-04: 62618072 (x86 Windows, 64 bit machine) # 2014-04-04: 62618072 (x86 Windows, 64 bit machine)
# 2014-09-03: 56315812 (x86 Windows, w/w for INLINEABLE) # 2014-09-03: 56315812 (x86 Windows, w/w for INLINABLE)
# 2014-12-01: 49987836 (x86 Windows) # 2014-12-01: 49987836 (x86 Windows)
# 2016-04-06: 55701280 (x86/Linux, 64-bit machine) # 2016-04-06: 55701280 (x86/Linux, 64-bit machine)
......
...@@ -2,4 +2,4 @@ module T7906 where ...@@ -2,4 +2,4 @@ module T7906 where
class Foo f where class Foo f where
foo :: f foo :: f
{-# INLINEABLE foo #-} {-# INLINABLE foo #-}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment