

I was wondering why you didn't use any INLINE pragmas in the Safe library. I'm not a Haskell expert yet, but I've noticed that in many other libraries most one-liners are annotated by INLINE pragmas, so is there any reason you didn't add them to Safe as well?



Prelude

Data.List

head

tail



tail :: [a] -> [a] , crashes on tail []

, crashes on

tailNote :: String -> [a] -> [a] , takes an extra argument which supplements the error message

, takes an extra argument which supplements the error message

tailDef :: [a] -> [a] -> [a] , takes a default to return instead of errors

, takes a default to return instead of errors

tailMay :: [a] -> Maybe [a] , wraps the result in a Maybe

, wraps the result in a

tailSafe :: [a] -> [a] , returns some sensible default if possible, [] in the case of tail



INLINE

tailSafe



tailSafe :: [a] -> [a]

tailSafe = liftSafe tail null



liftSafe :: (a -> a) -> (a -> Bool) -> (a -> a)

liftSafe func test val = if test val then val else func val



INLINE

tailSafe

ghc -ddump-hi Safe.hs -O -c

tailSafe



tailSafe = \val -> case val of

[] -> []

ds1:ds2 -> ds2



tailSafe

INLINE

INLINE

INLINE

tailSafe

Safe

-O0

-O1

-O2

abort

abort



abort = error



INLINE

abort

atMay

$watMay

atMay is recursive, and thus cannot be inlined even when it's definition is available, so GHC sensibly omits it from the interface file. The function $watMay is the worker/wrapper definition of atMay , which is also recursive.



readNote and readMay



The functions readNote and readMay both follow exactly the same pattern, so I describe only readNote . The function readNote is quite big, and GHC has split it into two top-level functions - producing both readNote and readNote1 . The function readNote is included in the interface file, but readNote1 is not. The result is that GHC will be able to partially inline the original definition of readNote - however, the read functions tend to be rather complex, so GHC is unlikely to benefit from the additional inlining it has managed to acheive.



atNote



The atNote function is bigger than the inlining threshold, so does not appear in the interface file unless an INLINE pragma is given. Since the inner loop of atNote is recursive, it is unlikely that inlining would give any noticable benefit, so GHC's default behaviour is appropriate.



Conclusion



Having analysed the interface files, I do not think it is worth adding INLINE pragmas to the Safe library - GHC does an excellent job without my intervention. My advice is to only add INLINE pragmas after either profiling, or analysing the resulting Core program.