{-# LANGUAGE Safe #-} {- | Copyright: (c) 2018-2021 Kowainik SPDX-License-Identifier: MIT Maintainer: Kowainik <xrom.xkov@gmail.com> Stability: Experimental Portability: Portable Contains useful functions to work with GHC callstack. @since 0.2.0 -} module Relude.Extra.CallStack ( ownName , callerName ) where import Relude {- | This function returns the name of its caller function, but it requires that the caller function has 'HasCallStack' constraint. Otherwise, it returns @"<unknown>"@. >>> foo :: HasCallStack => String; foo = ownName >>> foo "foo" >>> bar :: HasCallStack => String; bar = foo >>> bar "foo" @since 0.2.0 -} ownName :: HasCallStack => String ownName :: String ownName = case CallStack -> [(String, SrcLoc)] getCallStack CallStack HasCallStack => CallStack callStack of (String, SrcLoc) _:(String, SrcLoc) caller:[(String, SrcLoc)] _ -> (String, SrcLoc) -> String forall a b. (a, b) -> a fst (String, SrcLoc) caller [(String, SrcLoc)] _ -> String "<unknown>" {- | This function returns the name of its caller of the caller function, but it requires that the caller function and caller of the caller function have 'HasCallStack' constraint. Otherwise, it returns @"<unknown>"@. It's useful for logging: >>> log :: HasCallStack => String -> IO (); log s = putStrLn $ callerName ++ ":" ++ s >>> greeting :: HasCallStack => IO (); greeting = log "Starting..." >> putStrLn "Hello!" >> log "Ending..." >>> greeting greeting:Starting... Hello! greeting:Ending... @since 0.2.0 -} callerName :: HasCallStack => String callerName :: String callerName = case CallStack -> [(String, SrcLoc)] getCallStack CallStack HasCallStack => CallStack callStack of (String, SrcLoc) _:(String, SrcLoc) _:(String, SrcLoc) caller:[(String, SrcLoc)] _ -> (String, SrcLoc) -> String forall a b. (a, b) -> a fst (String, SrcLoc) caller [(String, SrcLoc)] _ -> String "<unknown>"