IsString [Char] instance

Greetings, Today, someone came into #haskell and asked why they couldn't type the equivalent of: > "hi" ++ "bye" into GHCi with OverloadedStrings enabled. The answer is that it's ambiguous, because (++) only determines the strings to be [a], and not [Char]. I noticed that this could actually be solved by making the instance: instance (a ~ Char) => IsString [a] where ... Which causes [Char] to be inferred as soon as [a] is. I then searched my libraries mail and noticed that we'd discussed this two years ago. The proposal for this instance change was rejected based on ExtendedDefaultRules being beefed up to solve this case. But then no one actually implemented the better defaulting. So, I'm proposing that the issue be fixed for real. I'm not terribly concerned with how it gets fixed, but there's not a great reason for this to not behave better than it currently does. If someone steps up and makes defaulting better, than that's great. But if not, then the libraries committee can fix this very easily for GHC 7.12, and I think it's better to do so than to wait if there are no signs that the alternative is going to happen. I don't think we need to nail down which of the two solutions we're going to choose right now, but it'd be good to resolve that we're going to fix it, one way or another, by some well defined date. Here's a link to the previous discussion: http://comments.gmane.org/gmane.comp.lang.haskell.libraries/20088 Discussion period: 2 weeks -- Dan

+1 from me. Let's resolve to do something about the situation before 7.12
ships.
I'd definitely prefer some kind of smarter defaulting, because that'd also
potentially address the length "foo" overloaded string problem that got
worse with the Foldable/Traversable Proposal, but even just the
instance (a ~ Char) => IsString [a]
solution goes a long way and has the benefit that it could be implemented
today without having to figure out and test complex defaulting rules.
-Edward
On Mon, May 18, 2015 at 10:08 AM, Dan Doel
Greetings,
Today, someone came into #haskell and asked why they couldn't type the equivalent of:
> "hi" ++ "bye"
into GHCi with OverloadedStrings enabled. The answer is that it's ambiguous, because (++) only determines the strings to be [a], and not [Char].
I noticed that this could actually be solved by making the instance:
instance (a ~ Char) => IsString [a] where ...
Which causes [Char] to be inferred as soon as [a] is. I then searched my libraries mail and noticed that we'd discussed this two years ago. The proposal for this instance change was rejected based on ExtendedDefaultRules being beefed up to solve this case. But then no one actually implemented the better defaulting.
So, I'm proposing that the issue be fixed for real. I'm not terribly concerned with how it gets fixed, but there's not a great reason for this to not behave better than it currently does. If someone steps up and makes defaulting better, than that's great. But if not, then the libraries committee can fix this very easily for GHC 7.12, and I think it's better to do so than to wait if there are no signs that the alternative is going to happen.
I don't think we need to nail down which of the two solutions we're going to choose right now, but it'd be good to resolve that we're going to fix it, one way or another, by some well defined date.
Here's a link to the previous discussion:
http://comments.gmane.org/gmane.comp.lang.haskell.libraries/20088
Discussion period: 2 weeks
-- Dan
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Have you tested this? If GHC sees two overlapping instances
instance ... => IsString [a]
instance IsString [Char]
it’ll refrain from using the former until it knows that the latter can’t match.
So the “extended defaulting rules” may actually be needed.
I’m not against beefing up the extended default rules if someone wants to write a specification. It wouldn’t be hard to do.
Simon
From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Edward Kmett
Sent: 18 May 2015 02:37
To: Dan Doel
Cc: Haskell Libraries
Subject: Re: IsString [Char] instance
+1 from me. Let's resolve to do something about the situation before 7.12 ships.
I'd definitely prefer some kind of smarter defaulting, because that'd also potentially address the length "foo" overloaded string problem that got worse with the Foldable/Traversable Proposal, but even just the
instance (a ~ Char) => IsString [a]
solution goes a long way and has the benefit that it could be implemented today without having to figure out and test complex defaulting rules.
-Edward
On Mon, May 18, 2015 at 10:08 AM, Dan Doel

On 2015-05-18 at 11:29:25 +0200, Simon Peyton Jones wrote:
Have you tested this? If GHC sees two overlapping instances instance ... => IsString [a] instance IsString [Char] it’ll refrain from using the former until it knows that the latter can’t match.
FWIW, the original stated problem of having GHC be able to infer "hi" ++ "bye" under the influence of -XOverloadedStrings which would cause GHC to complain λ:2> "foo" ++ "bar" <interactive>:2:1: Non type-variable argument in the constraint: Data.String.IsString [a] (Use FlexibleContexts to permit this) When checking that ‘it’ has the inferred type it :: forall a. Data.String.IsString [a] => [a] is actually resolved by the following patch (which I tried w/ GHC HEAD): --8<---------------cut here---------------start------------->8--- diff --git a/libraries/base/Data/String.hs b/libraries/base/Data/String.hs index a03569f..2bed477 100644 --- a/libraries/base/Data/String.hs +++ b/libraries/base/Data/String.hs @@ -1,5 +1,5 @@ {-# LANGUAGE Trustworthy #-} -{-# LANGUAGE NoImplicitPrelude, FlexibleInstances #-} +{-# LANGUAGE NoImplicitPrelude, GADTs #-} ----------------------------------------------------------------------------- -- | @@ -34,6 +34,6 @@ import Data.List (lines, words, unlines, unwords) class IsString a where fromString :: String -> a -instance IsString [Char] where +instance (a ~ Char) => IsString [a] where fromString xs = xs --8<---------------cut here---------------end--------------->8---

I'm +1 as well. I have a hard time thinking of a list of something besides
`Char`s for which we'd want an `IsString` instance to work for.
On Mon, May 18, 2015 at 4:36 AM Edward Kmett
+1 from me. Let's resolve to do something about the situation before 7.12 ships.
I'd definitely prefer some kind of smarter defaulting, because that'd also potentially address the length "foo" overloaded string problem that got worse with the Foldable/Traversable Proposal, but even just the
instance (a ~ Char) => IsString [a]
solution goes a long way and has the benefit that it could be implemented today without having to figure out and test complex defaulting rules.
-Edward
On Mon, May 18, 2015 at 10:08 AM, Dan Doel
wrote: Greetings,
Today, someone came into #haskell and asked why they couldn't type the equivalent of:
> "hi" ++ "bye"
into GHCi with OverloadedStrings enabled. The answer is that it's ambiguous, because (++) only determines the strings to be [a], and not [Char].
I noticed that this could actually be solved by making the instance:
instance (a ~ Char) => IsString [a] where ...
Which causes [Char] to be inferred as soon as [a] is. I then searched my libraries mail and noticed that we'd discussed this two years ago. The proposal for this instance change was rejected based on ExtendedDefaultRules being beefed up to solve this case. But then no one actually implemented the better defaulting.
So, I'm proposing that the issue be fixed for real. I'm not terribly concerned with how it gets fixed, but there's not a great reason for this to not behave better than it currently does. If someone steps up and makes defaulting better, than that's great. But if not, then the libraries committee can fix this very easily for GHC 7.12, and I think it's better to do so than to wait if there are no signs that the alternative is going to happen.
I don't think we need to nail down which of the two solutions we're going to choose right now, but it'd be good to resolve that we're going to fix it, one way or another, by some well defined date.
Here's a link to the previous discussion:
http://comments.gmane.org/gmane.comp.lang.haskell.libraries/20088
Discussion period: 2 weeks
-- Dan
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Michael Snoyman wrote:
I have a hard time thinking of a list of something besides `Char`s for which we'd want an `IsString` instance to work for.
I have an easy time. The `Data.Char` module is always woefully behind the Unicode standard, and there are always Unicode features that are implemented differently than what some people might want. A case in point is toUpper and toLower. Those were fixed in Data.Text, but are still broken in Data.Char. For me, so far this has not been important enough for me to need to implement my own Char type, or a newtype wrapper with improvements. But it is certainly conceivable that others might need this. Whether or not you like those examples - it is really the wrong approach to outlaw IsString [a] instance forever more for any a except Char. Yes, this is a serious problem that should be solved. But are we really giving up on doing it the right way and fixing defaulting rules? Simon wrote that it wouldn't be hard. I propose: Set a reasonable time limit for someone to step up and provide a suggested fix to the defaulting rules. If that doesn't happen, then bite the bullet and do it using the type equality Thanks, Yitz

You can always newtype your list. I'm opposed to having everyone suffer today just because someone someday may want to write an alternative instance. On 18/05/15 17:57, Yitzchak Gale wrote:
Michael Snoyman wrote:
I have a hard time thinking of a list of something besides `Char`s for which we'd want an `IsString` instance to work for.
I have an easy time. The `Data.Char` module is always woefully behind the Unicode standard, and there are always Unicode features that are implemented differently than what some people might want.
A case in point is toUpper and toLower. Those were fixed in Data.Text, but are still broken in Data.Char.
For me, so far this has not been important enough for me to need to implement my own Char type, or a newtype wrapper with improvements. But it is certainly conceivable that others might need this.
Whether or not you like those examples - it is really the wrong approach to outlaw IsString [a] instance forever more for any a except Char.
Yes, this is a serious problem that should be solved. But are we really giving up on doing it the right way and fixing defaulting rules? Simon wrote that it wouldn't be hard.
I propose: Set a reasonable time limit for someone to step up and provide a suggested fix to the defaulting rules. If that doesn't happen, then bite the bullet and do it using the type equality
Thanks, Yitz _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On Mon, May 18, 2015 at 10:57 AM, Yitzchak Gale
Michael Snoyman wrote:
I have a hard time thinking of a list of something besides `Char`s for which we'd want an `IsString` instance to work for.
I have an easy time. The `Data.Char` module is always woefully behind the Unicode standard, and there are always Unicode features that are implemented differently than what some people might want.
A case in point is toUpper and toLower. Those were fixed in Data.Text, but are still broken in Data.Char.
For me, so far this has not been important enough for me to need to implement my own Char type, or a newtype wrapper with improvements. But it is certainly conceivable that others might need this.
Whether or not you like those examples - it is really the wrong approach to outlaw IsString [a] instance forever more for any a except Char.
I'm a little skeptical that someone would be concerned about proper Unicode support and still want [Codepoint]---with no abstraction barrier---to be the string type. I think it'd even be good if we could ditch [Char] as the blessed string type in Haskell altogether. But that's a much more involved process.
Yes, this is a serious problem that should be solved. But are we really giving up on doing it the right way and fixing defaulting rules? Simon wrote that it wouldn't be hard.
It doesn't really matter how hard it is unless someone actually does it. I'm not exactly sure what people want out of beefed up defaulting, and what is feasible, either. Fixing 'show ("fizz" ++ "buzz")' is easy. If it also has to fix 'length "hello"', that may be more tricky, although it's something that the instance solution isn't really capable of fixing. So it's best not to get hung up on that. I propose: Set a reasonable time limit for someone to step
up and provide a suggested fix to the defaulting rules. If that doesn't happen, then bite the bullet and do it using the type equality
What is a reasonable time limit? It's been two years already. 7.12 is probably between 1/2 and 1 more. Do we really need more than that? -- Dan

I think we should ditch the notion that it's valid to round-trip from
Word32 to Char and back. Char should *only* take on valid codepoints
(although not only assigned ones). This will break some code
(particularly some weird stuff with file names, IIRC), but I think
that code is broken already. I don't, however, think that will fully
address Yitzchak's concerns.
On Mon, May 18, 2015 at 12:22 PM, Dan Doel
On Mon, May 18, 2015 at 10:57 AM, Yitzchak Gale
wrote: Michael Snoyman wrote:
I have a hard time thinking of a list of something besides `Char`s for which we'd want an `IsString` instance to work for.
I have an easy time. The `Data.Char` module is always woefully behind the Unicode standard, and there are always Unicode features that are implemented differently than what some people might want.
A case in point is toUpper and toLower. Those were fixed in Data.Text, but are still broken in Data.Char.
For me, so far this has not been important enough for me to need to implement my own Char type, or a newtype wrapper with improvements. But it is certainly conceivable that others might need this.
Whether or not you like those examples - it is really the wrong approach to outlaw IsString [a] instance forever more for any a except Char.
I'm a little skeptical that someone would be concerned about proper Unicode support and still want [Codepoint]---with no abstraction barrier---to be the string type. I think it'd even be good if we could ditch [Char] as the blessed string type in Haskell altogether. But that's a much more involved process.
Yes, this is a serious problem that should be solved. But are we really giving up on doing it the right way and fixing defaulting rules? Simon wrote that it wouldn't be hard.
It doesn't really matter how hard it is unless someone actually does it.
I'm not exactly sure what people want out of beefed up defaulting, and what is feasible, either. Fixing 'show ("fizz" ++ "buzz")' is easy. If it also has to fix 'length "hello"', that may be more tricky, although it's something that the instance solution isn't really capable of fixing. So it's best not to get hung up on that.
I propose: Set a reasonable time limit for someone to step up and provide a suggested fix to the defaulting rules. If that doesn't happen, then bite the bullet and do it using the type equality
What is a reasonable time limit? It's been two years already. 7.12 is probably between 1/2 and 1 more. Do we really need more than that?
-- Dan
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On 2015-05-18 at 02:08:04 +0200, Dan Doel wrote:
Today, someone came into #haskell and asked why they couldn't type the equivalent of:
> "hi" ++ "bye"
into GHCi with OverloadedStrings enabled.
A minor observation: had (s)he used <> instead, GHCi would have happily inferred (and somewhat surprisingly reduced to a polymorphic "foobar"): GHCi, version 7.10.1: http://www.haskell.org/ghc/ :? for help λ:2> "foo" <> "bar" "foobar" it :: (Data.String.IsString m, Monoid m) => m

So, I rather lost track of this. It has been (significantly) more than
the specified amount of time, though.
No one has stepped up to specify/implement the new extended defaulting
to my knowledge. I'm not sure how much time is left before 7.12, but I
would guess it'd be tight for someone to start on this now. Perhaps
I'm wrong.
Anyhow, I think we should modify the instance at this point. I think
it's even cool to say we can roll it back if someone decides to beef
up defaulting, in which case rolling it back should cause no
regressions. But it doesn't seem like defaulting is going to happen.
-- Dan
On Sun, May 17, 2015 at 8:08 PM, Dan Doel
Greetings,
Today, someone came into #haskell and asked why they couldn't type the equivalent of:
> "hi" ++ "bye"
into GHCi with OverloadedStrings enabled. The answer is that it's ambiguous, because (++) only determines the strings to be [a], and not [Char].
I noticed that this could actually be solved by making the instance:
instance (a ~ Char) => IsString [a] where ...
Which causes [Char] to be inferred as soon as [a] is. I then searched my libraries mail and noticed that we'd discussed this two years ago. The proposal for this instance change was rejected based on ExtendedDefaultRules being beefed up to solve this case. But then no one actually implemented the better defaulting.
So, I'm proposing that the issue be fixed for real. I'm not terribly concerned with how it gets fixed, but there's not a great reason for this to not behave better than it currently does. If someone steps up and makes defaulting better, than that's great. But if not, then the libraries committee can fix this very easily for GHC 7.12, and I think it's better to do so than to wait if there are no signs that the alternative is going to happen.
I don't think we need to nail down which of the two solutions we're going to choose right now, but it'd be good to resolve that we're going to fix it, one way or another, by some well defined date.
Here's a link to the previous discussion:
http://comments.gmane.org/gmane.comp.lang.haskell.libraries/20088
Discussion period: 2 weeks
-- Dan

I'm fully on board with just moving ahead with this simple change for now.
It'd be nice to have a better defaulting story, but I'm not sure there _is_
a perfect solution in the wings.
-Edward
On Wed, Aug 12, 2015 at 12:14 PM, Dan Doel
So, I rather lost track of this. It has been (significantly) more than the specified amount of time, though.
No one has stepped up to specify/implement the new extended defaulting to my knowledge. I'm not sure how much time is left before 7.12, but I would guess it'd be tight for someone to start on this now. Perhaps I'm wrong.
Anyhow, I think we should modify the instance at this point. I think it's even cool to say we can roll it back if someone decides to beef up defaulting, in which case rolling it back should cause no regressions. But it doesn't seem like defaulting is going to happen.
-- Dan
Greetings,
Today, someone came into #haskell and asked why they couldn't type the equivalent of:
> "hi" ++ "bye"
into GHCi with OverloadedStrings enabled. The answer is that it's ambiguous, because (++) only determines the strings to be [a], and not [Char].
I noticed that this could actually be solved by making the instance:
instance (a ~ Char) => IsString [a] where ...
Which causes [Char] to be inferred as soon as [a] is. I then searched my libraries mail and noticed that we'd discussed this two years ago. The proposal for this instance change was rejected based on ExtendedDefaultRules being beefed up to solve this case. But then no one actually implemented
better defaulting.
So, I'm proposing that the issue be fixed for real. I'm not terribly concerned with how it gets fixed, but there's not a great reason for
On Sun, May 17, 2015 at 8:08 PM, Dan Doel
wrote: the this to not behave better than it currently does. If someone steps up and makes defaulting better, than that's great. But if not, then the libraries committee can fix this very easily for GHC 7.12, and I think it's better to do so than to wait if there are no signs that the alternative is going to happen.
I don't think we need to nail down which of the two solutions we're going to choose right now, but it'd be good to resolve that we're going to fix it, one way or another, by some well defined date.
Here's a link to the previous discussion:
http://comments.gmane.org/gmane.comp.lang.haskell.libraries/20088
Discussion period: 2 weeks
-- Dan
Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

I'm in favor of this as well.
On Thu, Aug 13, 2015 at 6:44 AM, Edward Kmett
I'm fully on board with just moving ahead with this simple change for now. It'd be nice to have a better defaulting story, but I'm not sure there _is_ a perfect solution in the wings.
-Edward
On Wed, Aug 12, 2015 at 12:14 PM, Dan Doel
wrote: So, I rather lost track of this. It has been (significantly) more than the specified amount of time, though.
No one has stepped up to specify/implement the new extended defaulting to my knowledge. I'm not sure how much time is left before 7.12, but I would guess it'd be tight for someone to start on this now. Perhaps I'm wrong.
Anyhow, I think we should modify the instance at this point. I think it's even cool to say we can roll it back if someone decides to beef up defaulting, in which case rolling it back should cause no regressions. But it doesn't seem like defaulting is going to happen.
-- Dan
Greetings,
Today, someone came into #haskell and asked why they couldn't type the equivalent of:
> "hi" ++ "bye"
into GHCi with OverloadedStrings enabled. The answer is that it's ambiguous, because (++) only determines the strings to be [a], and not [Char].
I noticed that this could actually be solved by making the instance:
instance (a ~ Char) => IsString [a] where ...
Which causes [Char] to be inferred as soon as [a] is. I then searched my libraries mail and noticed that we'd discussed this two years ago. The proposal for this instance change was rejected based on ExtendedDefaultRules being beefed up to solve this case. But then no one actually implemented the better defaulting.
So, I'm proposing that the issue be fixed for real. I'm not terribly concerned with how it gets fixed, but there's not a great reason for
On Sun, May 17, 2015 at 8:08 PM, Dan Doel
wrote: this to not behave better than it currently does. If someone steps up and makes defaulting better, than that's great. But if not, then the libraries committee can fix this very easily for GHC 7.12, and I think it's better to do so than to wait if there are no signs that the alternative is going to happen.
I don't think we need to nail down which of the two solutions we're going to choose right now, but it'd be good to resolve that we're going to fix it, one way or another, by some well defined date.
Here's a link to the previous discussion:
http://comments.gmane.org/gmane.comp.lang.haskell.libraries/20088
Discussion period: 2 weeks
-- Dan
Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
participants (8)
-
Dan Doel
-
David Feuer
-
Edward Kmett
-
Herbert Valerio Riedel
-
Michael Snoyman
-
Roman Cheplyaka
-
Simon Peyton Jones
-
Yitzchak Gale