    {-# LANGUAGE ConstraintKinds #-}
    {-# LANGUAGE KindSignatures  #-}
    {-# LANGUAGE CPP             #-}
    {-# LANGUAGE ImplicitParams  #-}

    -- | ConstraintKind synonym for marking partial functions
    module Safe.Partial(Partial) where

    -- Let things work through ghci alone
    #ifndef MIN_VERSION_base
    #define MIN_VERSION_base(x,y,z) 1
    #endif

    -- GHC has changed its opinion on the location a few times
    -- v0: GHC 7.4.1, has ConstraintKinds
    -- v1: GHC 7.10.2, base 4.8.1.0 = CallStack
    -- v2: GHC 8.0.1, base 4.9.0.0 = HasCallStack

    #if __GLASGOW_HASKELL__ >= 800
    #define OPTION 2
    #elif __GLASGOW_HASKELL__ >= 710 && MIN_VERSION_base(4,8,1)
    #define OPTION 1
    #else
    #define OPTION 0
    #endif

    #if OPTION == 0
    import GHC.Exts
    #else
    import GHC.Stack
    #endif

    -- | A constraint synonym which denotes that the function is partial, and will
    --   (on GHC 8.* and up) produce a stack trace on failure.
    --   You may mark your own non-total functions as Partial, if necessary, and this
    --   will ensure that they produce useful stack traces.
    #if OPTION == 0
    type Partial = (() :: Constraint)
    #elif OPTION == 1
    type Partial = (?loc :: CallStack)
    #else
    type Partial = HasCallStack
    #endif