-- | This module can be useful while /developing/ an application. It should not -- be used in production. module Debug ( -- * Debugging toString, log, todo, ) where import Basics ((>>)) import Data.Text (pack, unpack) import qualified Debug.Trace import qualified GHC.Stack as Stack import Text (Text, concat) import qualified Text.Show.Pretty import Prelude (Show, error) -- | Turn any @Show@able kind of value into a string. -- -- > toString 42 == "42" -- > toString [1,2] == "[1,2]" -- > toString ('a', "cat", 13) == "('a', \"cat\", 13)" -- > toString "he said, \"hi\"" == "\"he said, \\\"hi\\\"\"" -- -- Notice that with strings, this is not the @identity@ function. Ultimately it's -- down to the value's @Show@ instance, but for strings this typically escapes -- characters. If you say @toString "he said, \\"hi\\""@ it will show @"he said, -- \\"hi\\""@ rather than @he said, "hi"@. toString :: Show a => a -> Text toString :: a -> Text toString = a -> String forall a. Show a => a -> String Text.Show.Pretty.ppShow (a -> String) -> (String -> Text) -> a -> Text forall a b c. (a -> b) -> (b -> c) -> a -> c >> String -> Text pack -- | Log a tagged value on the developer console, and then return the value. -- -- > 1 + log "number" 1 -- equals 2, logs "number: 1" -- > length (log "start" []) -- equals 0, logs "start: []" -- -- It is often possible to sprinkle this around to see if values are what you -- expect. It is kind of old-school to do it this way, but it works! log :: Show a => Text -> a -> a log :: Text -> a -> a log Text message a value = String -> a -> a forall a. String -> a -> a Debug.Trace.trace (Text -> String unpack (List Text -> Text concat [Text message, Text ": ", a -> Text forall a. Show a => a -> Text toString a value])) a value -- | This is a placeholder for code that you will write later. -- -- For example, if you are working with a large union type and have partially -- completed a case expression, it may make sense to do this: -- -- > type Entity = Ship | Fish | Captain | Seagull -- > -- > drawEntity entity = -- > case entity of -- > Ship -> -- > ... -- > -- > Fish -> -- > ... -- > -- > _ -> -- > Debug.todo "handle Captain and Seagull" -- -- When you call this it throws an exception with the message you give. That -- exception is catchable... but don't. todo :: Stack.HasCallStack => Text -> a todo :: Text -> a todo = (HasCallStack => Text -> a) -> Text -> a forall a. HasCallStack => (HasCallStack => a) -> a Stack.withFrozenCallStack (Text -> String unpack (Text -> String) -> (String -> a) -> Text -> a forall a b c. (a -> b) -> (b -> c) -> a -> c >> String -> a forall a. HasCallStack => String -> a error)