Compile-time validation of literals in IsString instances
I would like to be able to make IsString
instances using the OverloadedStrings
extension such that my instance rejects some literals as being invalid and such that that rejection happens at compile time, so that programming mistakes don't make it into the code I give to my users.
I have a couple of use cases where I have a Name
type that only admits certain strings. e.g.
module Name (Name(getName), makeName) where
import Data.Text (Text)
import qualified Data.Text as Text
-- | A guaranteed non-empty name.
newtype Name = Name { getName :: Text } deriving (Eq, Show, Ord)
makeName :: Text -> Maybe Name
makeName name
| Text.null name = Nothing
| otherwise = Just name
In a real use case, I'd check for valid characters, not starting with a digit, that sort of thing.
The idea is that we don't export the Name
constructor, which means anyone using a Name
value can trust that it has certain properties (in this case, non-empty).
My problem is that I'd like to use literal names in many places. e.g.
programName :: Name
programName = fromJust $ makeName "the-great-and-powerful-turtle"
Because I do this a lot, I've defined an unsafeMakeName
helper that does pretty much the same thing:
unsafeMakeName :: Text -> Name
unsafeMakeName name = fromMaybe (error $ "Invalid name: " <> Text.unpack name) (makeName name)
The problem with this approach is that even though the cause of the mistake is a programming error, I don't find out about it until run time.
What I'd like to do is write an IsString
instance for Name
which does that validation, e.g.
instance IsString Name where
fromString = unsafeMakeName . Text.pack
- .. but to get the error about invalid names in literals at compile-time. This doesn't seem logically impossible to me, since the compiler could know the values of literals with certainty.
Trac metadata
Trac field | Value |
---|---|
Version | 8.0.1 |
Type | FeatureRequest |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |