Haskell error reporting with locations, update
Since some people (I'm among them) dislike impure features in Haskell I thought I'd present a slight variation on the error location feature that is "pure".
First, the __LOCATION__ variable gets an abstract type. So
data Location __LOCATION__ :: LocationIt's defined in the Prelude and always in scope. The type cannot be compared, shown, or anything. There's just one thing that can be done, namely:
extractLocation :: Location -> IO StringThe error function needs a new exception to throw
data ErrorCallLoc = ErrorCallLoc Location String {-# LOCATIONTRANSPARENT error #-} error :: String -> a error s = throw (ErrorCallLoc __LOCATION__ s)This means that the location string cannot be used when we throw the error. But it can be used where the error is caught, since this can only be done in the IO monad.
Under the hood the everything is just as before, Location is just a string. It just can't be manipulated except in the IO monad, so we can pretend it's pure.
newtype Location = Location String extractLocation (Location s) = return sIt now looks a lot like Michael Snoyman's proposal.
1 Comments:
Indeed it is much nicer to locate exceptions in pure functions.
Would that proposal also involve adding Location to every Exception now in base?
Post a Comment
<< Home