I'm aware that the OverloadedStrings
language pragma wraps an implicit fromString
around all string literals. What I'd like to do is not actually overload strings, but merely change their meaning so that they are always turned into Text
, and therefore, using a string literal as a list of characters should result in a type error.
It appears to be impossible to import the IsString
class without also importing the String
instance for that class. Does ghc provide some way for me to restrict string literals to Text
only?
Not a way to achieve this now, but maybe eventually, is the
instance force
as proposed in a GHC feature proposal under discussion, where you’d sayin your module. This is one of the main motivating examples for the proposal.
It's a little bit of overkill, but one solution is to combine
OverloadedStrings
andRebindableSyntax
. TheRebindableSyntax
extension causes all the implicit function calls that Haskell syntax uses to refer to whatever functions are in scope; for instance, integer literals use anyfromIntegral
, not necessarilyPrelude.fromIntegral
. As a side effect,Prelude
is no longer implicitly imported, so you have to do that manually. As long as you do import it, there shouldn't be any issues with syntax using the wrong function implicitly (I think—I haven't actually used this technique). When combined withOverloadedStrings
, this causes"foo"
to be transformed intofromString "foo"
for whateverfromString
's in scope, not necessarilyData.String.fromString "foo"
. So makingfromString
synonymous withpack
will do what you want. A complete example:This works fine, and changing
main
tomain = putStrLn "Hello, world!"
produces the desired error:Commenting out the definition of
fromString
causes a different error:If you want it to work with both strict and lazy text, you could define your own
IsString
type class, and make both of them instances; the class doesn't have to be calledIsString
, just so long as it has afromString
method.Also, a word of warning: the section of the GHC manual on
RebindableSyntax
doesn't mention thefromString
function, and the section onOverloadedStrings
doesn't mentionRebindableSyntax
. There's no reason this shouldn't work, but I think that means that this solution technically relies on undocumented behavior.