descript-lang-0.2.0.0: src/Descript/Misc/Summary.hs
{-# LANGUAGE Rank2Types #-}
module Descript.Misc.Summary
( Summary (..)
) where
import Data.Ratio
import Data.List
import Data.List.NonEmpty (NonEmpty)
import qualified Data.List.NonEmpty as NonEmpty
import Data.Text (Text)
import Text.Megaparsec.Pos
-- | Can generate a debug description. Summaries explicitly /don't/ need
-- to provide all information about an object - this makes them
-- different than 'Show'.
class (Show a) => Summary a where
{-# MINIMAL summary | summaryRec #-}
-- | A debug description. Summaries explicitly /don't/ need to provide
-- all information about an object - this makes them different than 'Show'.
-- If the implementation calls the summary of sub-expressions, use
-- 'summaryRec' instead.
summary :: a -> String
summary = summaryRec summary
-- | A debug description. Summaries explicitly /don't/ need to provide
-- all information about an object - this makes them different than 'Show'.
-- Can modify the summaries of sub-expressions using the given function.
summaryRec :: (forall b. (Summary b) => b -> String) -> a -> String
summaryRec _ = summary
-- | A summary of a list of these items, given a function which gets a
-- summary of each item. Overridden by 'Char', like 'showsList', for strings.
summaryList :: (a -> String) -> [a] -> String
summaryList subSummary xs = "[" ++ intercalate ", " childSummaries ++ "]"
where childSummaries = map subSummary xs
instance Summary Char where
summary = show
summaryList _ = show
instance Summary Int where
summary = show
instance Summary Integer where
summary = show
instance Summary Float where
summary = show
instance Summary Double where
summary = show
instance Summary Pos where
summary = summary . unPos
instance Summary Text where
summary = show
instance (Summary a) => Summary (Ratio a) where
summaryRec subSummary x
| denomSummary == "1" = numSummary
| otherwise = numSummary ++ "/" ++ denomSummary
where numSummary = subSummary $ numerator x
denomSummary = subSummary $ denominator x
instance (Summary a) => Summary (Maybe a) where
summaryRec _ Nothing = "(nothing)"
summaryRec sub (Just x) = sub x
instance (Summary a) => Summary [a] where
summaryRec = summaryList
instance (Summary a) => Summary (NonEmpty a) where
summaryRec subSummary = summaryRec subSummary . NonEmpty.toList
instance (Summary a, Summary b) => Summary (a, b) where
summaryRec subSummary (x, y) = "(" ++ subSummary x ++ ", " ++ subSummary y ++ ")"