descript-lang-0.2.0.0: src/Descript/Free/Error.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Descript.Free.Error
( RefineResult
, RefineDiff (..)
, IndivRefineDiff (..)
, LocalRefineDiff (..)
, entireRefineDiff
, actualSummary
, diffErrorDesc
) where
import Descript.Misc
-- | The result of trying to refine a free value.
type RefineResult a = Result RefineDiff a
-- | When a term can't be refined because it has the wrong shape,
-- describes which parts of the term have the wrong shape, and for each
-- part, what shape was expected and given.
newtype RefineDiff = RefineDiff [IndivRefineDiff] deriving (Eq, Ord, Read, Show, Monoid)
-- | When a term can't be refined because a sub-term has the wrong shape,
-- describes the range of the sub-term with the wrong shape, and what shape
-- was expected and given.
data IndivRefineDiff
= IndivRefineDiff
{ range :: Range
, localDiff :: LocalRefineDiff
} deriving (Eq, Ord, Read, Show)
-- | When a term can't be refined because the entire term has the wrong
-- shape, describes what shape was expected and what shape this term has.
data LocalRefineDiff
= LocalRefineDiff
{ expected :: String
, actual :: String
, actualPr :: String
} deriving (Eq, Ord, Read, Show)
instance Summary RefineDiff where
summary = msgToStr . diffErrorDesc
instance Summary IndivRefineDiff where
summary = indivDiffErrorDesc
instance Summary LocalRefineDiff where
summary = localDiffErrorDesc
-- | States that an entire term's shape is wrong.
entireRefineDiff :: Range -> LocalRefineDiff -> RefineDiff
entireRefineDiff range' x
= RefineDiff
[ IndivRefineDiff{range = range', localDiff = x}
]
-- | Gets a description of the refine difference.
diffErrorDesc :: RefineDiff -> ErrorMsg
diffErrorDesc (RefineDiff xs) = ErrorMsg $ map indivDiffErrorDesc xs
indivDiffErrorDesc :: IndivRefineDiff -> String
indivDiffErrorDesc indiv
= summary (range indiv)
++ ": "
++ localDiffErrorDesc (localDiff indiv)
localDiffErrorDesc :: LocalRefineDiff -> String
localDiffErrorDesc diff
= actualPr diff
++ ": expected "
++ expected diff
++ ", got "
++ actual diff
-- | Combines the actual print and term label to form a summary of the
-- actual item in a refine diff.
actualSummary :: LocalRefineDiff -> String
actualSummary diff = actual diff ++ " \"" ++ actualPr diff ++ "\""