Proposal: Improving the IsString String instance

I've been chewing on this one for a long time, and finally decided to post it after being bitten by it *again*. Right now we have a very fragile instance in base for instance IsString String where fromString = id This is fragile because once you turn on OverloadedStrings length "hello" won't work any more, because all it knows is that it has a [a] such that it needs an IsString [a] instance, but it can't use defaulting to select the [Char] instance we've defined, and so you have to burden it with a type annotation.
:set -XOverloadedStrings length "hello"
<interactive>:3:8: No instance for (Data.String.IsString [a0]) arising from the literal `"hello"' The type variable `a0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there is a potential instance available: instance Data.String.IsString [Char] -- Defined in `Data.String' Possible fix: add an instance declaration for (Data.String.IsString [a0]) In the first argument of `length', namely `"hello"' In the expression: length "hello" In an equation for `it': it = length "hello" I would like to replace this instance with instance a ~ Char => IsString [a] where fromString = id This will make OverloadedStrings work much better with the list-specific combinators, reducing the number of type annotations required by users who hack on, say, web-apps in Haskell where both OverloadedStrings is a common extension and, frankly, the users are often the least equipped to deal with and understand the issue. The cost of this instance is that someone else can't come along and make an instance of IsString for another 'character-like' type and get the String-like behavior with magic list interoperability without some kind of wrapper. However, I've yet to see any such instances, and I'd likely look down my nose at such an instance in the first place. ;) The current pain is real and the space of instances affected seems both largely theoretical and a bad idea to begin with. The instance is already guarded from use by NHC by an #ifdef, which limits objections on portability grounds. Discussion Period: 2 Weeks

On Sat, Aug 24, 2013 at 8:52 PM, Edward Kmett
I've been chewing on this one for a long time, and finally decided to post it after being bitten by it *again*.
Right now we have a very fragile instance in base for
instance IsString String where fromString = id
This is fragile because once you turn on OverloadedStrings
length "hello"
won't work any more, because all it knows is that it has a [a] such that it needs an IsString [a] instance, but it can't use defaulting to select the [Char] instance we've defined, and so you have to burden it with a type annotation.
:set -XOverloadedStrings length "hello"
<interactive>:3:8: No instance for (Data.String.IsString [a0]) arising from the literal `"hello"' The type variable `a0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there is a potential instance available: instance Data.String.IsString [Char] -- Defined in `Data.String' Possible fix: add an instance declaration for (Data.String.IsString [a0]) In the first argument of `length', namely `"hello"' In the expression: length "hello" In an equation for `it': it = length "hello"
I would like to replace this instance with
instance a ~ Char => IsString [a] where fromString = id
This will make OverloadedStrings work much better with the list-specific combinators, reducing the number of type annotations required by users who hack on, say, web-apps in Haskell where both OverloadedStrings is a common extension and, frankly, the users are often the least equipped to deal with and understand the issue.
The cost of this instance is that someone else can't come along and make an instance of IsString for another 'character-like' type and get the String-like behavior with magic list interoperability without some kind of wrapper.
However, I've yet to see any such instances, and I'd likely look down my nose at such an instance in the first place. ;) The current pain is real and the space of instances affected seems both largely theoretical and a bad idea to begin with.
The instance is already guarded from use by NHC by an #ifdef, which limits objections on portability grounds.
Discussion Period: 2 Weeks
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
This seems like a good overall change to me. I understand that we're giving up some flexibility, but the user-facing simplicity is probably worth it. +1 from here.

+1
OverloadedStrings is meant as a convenience, this ensures it better
satisfies that goal.
On 24 August 2013 20:20, Michael Snoyman
On Sat, Aug 24, 2013 at 8:52 PM, Edward Kmett
wrote: I've been chewing on this one for a long time, and finally decided to post it after being bitten by it *again*.
Right now we have a very fragile instance in base for
instance IsString String where fromString = id
This is fragile because once you turn on OverloadedStrings
length "hello"
won't work any more, because all it knows is that it has a [a] such that it needs an IsString [a] instance, but it can't use defaulting to select the [Char] instance we've defined, and so you have to burden it with a type annotation.
:set -XOverloadedStrings length "hello"
<interactive>:3:8: No instance for (Data.String.IsString [a0]) arising from the literal `"hello"' The type variable `a0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there is a potential instance available: instance Data.String.IsString [Char] -- Defined in `Data.String' Possible fix: add an instance declaration for (Data.String.IsString [a0]) In the first argument of `length', namely `"hello"' In the expression: length "hello" In an equation for `it': it = length "hello"
I would like to replace this instance with
instance a ~ Char => IsString [a] where fromString = id
This will make OverloadedStrings work much better with the list-specific combinators, reducing the number of type annotations required by users who hack on, say, web-apps in Haskell where both OverloadedStrings is a common extension and, frankly, the users are often the least equipped to deal with and understand the issue.
The cost of this instance is that someone else can't come along and make an instance of IsString for another 'character-like' type and get the String-like behavior with magic list interoperability without some kind of wrapper.
However, I've yet to see any such instances, and I'd likely look down my nose at such an instance in the first place. ;) The current pain is real and the space of instances affected seems both largely theoretical and a bad idea to begin with.
The instance is already guarded from use by NHC by an #ifdef, which limits objections on portability grounds.
Discussion Period: 2 Weeks
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
This seems like a good overall change to me. I understand that we're giving up some flexibility, but the user-facing simplicity is probably worth it. +1 from here.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

+1!
On Sat, Aug 24, 2013 at 11:10 PM, John Wiegley
Christopher Done
writes: +1 OverloadedStrings is meant as a convenience, this ensures it better satisfies that goal.
+1
-- John Wiegley FP Complete Haskell tools, training and consulting http://fpcomplete.com johnw on #haskell/irc.freenode.net
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

+1 from me; I think this is why I have let s = id :: String -> String in my
~/.ghci and I agree the usefulness of being able to add other IsString
[a]instances is debatable and dubious, and the benefits from improved
defaulting of far greater value here.
On Sat, Aug 24, 2013 at 7:52 PM, Edward Kmett
I've been chewing on this one for a long time, and finally decided to post it after being bitten by it *again*.
Right now we have a very fragile instance in base for
instance IsString String where fromString = id
This is fragile because once you turn on OverloadedStrings
length "hello"
won't work any more, because all it knows is that it has a [a] such that it needs an IsString [a] instance, but it can't use defaulting to select the [Char] instance we've defined, and so you have to burden it with a type annotation.
:set -XOverloadedStrings length "hello"
<interactive>:3:8: No instance for (Data.String.IsString [a0]) arising from the literal `"hello"' The type variable `a0' is ambiguous Possible fix: add a type signature that fixes these type variable(s) Note: there is a potential instance available: instance Data.String.IsString [Char] -- Defined in `Data.String' Possible fix: add an instance declaration for (Data.String.IsString [a0]) In the first argument of `length', namely `"hello"' In the expression: length "hello" In an equation for `it': it = length "hello"
I would like to replace this instance with
instance a ~ Char => IsString [a] where fromString = id
This will make OverloadedStrings work much better with the list-specific combinators, reducing the number of type annotations required by users who hack on, say, web-apps in Haskell where both OverloadedStrings is a common extension and, frankly, the users are often the least equipped to deal with and understand the issue.
The cost of this instance is that someone else can't come along and make an instance of IsString for another 'character-like' type and get the String-like behavior with magic list interoperability without some kind of wrapper.
However, I've yet to see any such instances, and I'd likely look down my nose at such an instance in the first place. ;) The current pain is real and the space of instances affected seems both largely theoretical and a bad idea to begin with.
The instance is already guarded from use by NHC by an #ifdef, which limits objections on portability grounds.
Discussion Period: 2 Weeks
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Am 24.08.2013 19:52, schrieb Edward Kmett:
I would like to replace this instance with
instance a ~ Char => IsString [a] where fromString = id
Your complaint proves my concerns about those FlexibleInstances. The best instance is a Haskell 98 instance: class IsCharList a where fromCharList :: [a] -> String instance IsCharList Char where fromCharList = id instance IsCharList a => IsString [a] where fromString = fromCharList This is both the most flexible solution and it is portable. http://www.haskell.org/haskellwiki/List_instance

On 25 August 2013 19:48, Henning Thielemann
Am 24.08.2013 19:52, schrieb Edward Kmett:
I would like to replace this instance with
instance a ~ Char => IsString [a] where fromString = id
Your complaint proves my concerns about those FlexibleInstances. The best instance is a Haskell 98 instance:
class IsCharList a where fromCharList :: [a] -> String
instance IsCharList Char where fromCharList = id
instance IsCharList a => IsString [a] where fromString = fromCharList
+1 to Henning's proposal.
This is both the most flexible solution and it is portable.
http://www.haskell.org/haskellwiki/List_instance
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
-- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com http://IvanMiljenovic.wordpress.com

This is a great idea! But 'a' may not always be a char-like thing. Maybe chunk is a better name? We could make instances for other string-like types, giving the recommended way to concat a list of string-like things.
class IsStringChunk a where
fromChunkList :: [a] -> String
instance IsStringChunk Char where
fromChunkList = id
instance IsStringChunk a => IsString [a] where
fromString = fromChunkList
Sjoerd
On Aug 25, 2013, at 11:48 AM, Henning Thielemann
Am 24.08.2013 19:52, schrieb Edward Kmett:
I would like to replace this instance with
instance a ~ Char => IsString [a] where fromString = id
Your complaint proves my concerns about those FlexibleInstances. The best instance is a Haskell 98 instance:
class IsCharList a where fromCharList :: [a] -> String
instance IsCharList Char where fromCharList = id
instance IsCharList a => IsString [a] where fromString = fromCharList
This is both the most flexible solution and it is portable.
http://www.haskell.org/haskellwiki/List_instance
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Sold. Now all everyone has to do is bikeshed the names. ;) -Edward On Sun, Aug 25, 2013 at 5:48 AM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote:
Am 24.08.2013 19:52, schrieb Edward Kmett:
I would like to replace this instance with
instance a ~ Char => IsString [a] where fromString = id
Your complaint proves my concerns about those FlexibleInstances. The best instance is a Haskell 98 instance:
class IsCharList a where fromCharList :: [a] -> String
instance IsCharList Char where fromCharList = id
instance IsCharList a => IsString [a] where fromString = fromCharList
This is both the most flexible solution and it is portable.
http://www.haskell.org/**haskellwiki/List_instancehttp://www.haskell.org/haskellwiki/List_instance

[Apologies to Henning and Edward for duplicate email] On Sun, Aug 25, 2013 at 5:48 AM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote:
Am 24.08.2013 19:52, schrieb Edward Kmett:
I would like to replace this instance with
instance a ~ Char => IsString [a] where fromString = id
Your complaint proves my concerns about those FlexibleInstances. The best instance is a Haskell 98 instance:
class IsCharList a where fromCharList :: [a] -> String
instance IsCharList Char where fromCharList = id
instance IsCharList a => IsString [a] where fromString = fromCharList
This is both the most flexible solution and it is portable.
http://www.haskell.org/**haskellwiki/List_instancehttp://www.haskell.org/haskellwiki/List_instance
This doesn't compile (in the IsString instance, we need fromString :: String -> [a], but we have fromCharList :: [a] -> String), and if you fix the declaration of fromCharList to fromCharList :: String -> [a], it fails to achieve the goal that was the original purpose of Edward's proposal. See below, where I've used RebindableSyntax to write a custom IsString class to avoid overlapping with the built-in instance IsString String. {-# LANGUAGE RebindableSyntax, OverloadedStrings #-} import Prelude(Char, String, id, length, print) class IsString a where fromString :: String -> a class IsCharList a where fromCharList :: String -> [a] instance IsCharList Char where fromCharList = id instance IsCharList a => IsString [a] where fromString = fromCharList main = print (length "abc") {- /tmp/is.hs:17:22: Ambiguous type variable `a0' in the constraint: (IsCharList a0) arising from the literal `"abc"' Probable fix: add a type signature that fixes these type variable(s) In the first argument of `length', namely `"abc"' In the first argument of `print', namely `(length "abc")' In the expression: print (length "abc") -} Regards, Reid Barton

Looks like that takes us back to the original proposal.
-Edward
On Sun, Aug 25, 2013 at 10:22 AM, Reid Barton
[Apologies to Henning and Edward for duplicate email]
On Sun, Aug 25, 2013 at 5:48 AM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote:
Am 24.08.2013 19:52, schrieb Edward Kmett:
I would like to replace this instance with
instance a ~ Char => IsString [a] where fromString = id
Your complaint proves my concerns about those FlexibleInstances. The best instance is a Haskell 98 instance:
class IsCharList a where fromCharList :: [a] -> String
instance IsCharList Char where fromCharList = id
instance IsCharList a => IsString [a] where fromString = fromCharList
This is both the most flexible solution and it is portable.
http://www.haskell.org/**haskellwiki/List_instancehttp://www.haskell.org/haskellwiki/List_instance
This doesn't compile (in the IsString instance, we need fromString :: String -> [a], but we have fromCharList :: [a] -> String), and if you fix the declaration of fromCharList to fromCharList :: String -> [a], it fails to achieve the goal that was the original purpose of Edward's proposal. See below, where I've used RebindableSyntax to write a custom IsString class to avoid overlapping with the built-in instance IsString String.
{-# LANGUAGE RebindableSyntax, OverloadedStrings #-}
import Prelude(Char, String, id, length, print)
class IsString a where fromString :: String -> a
class IsCharList a where fromCharList :: String -> [a]
instance IsCharList Char where fromCharList = id
instance IsCharList a => IsString [a] where fromString = fromCharList
main = print (length "abc")
{- /tmp/is.hs:17:22: Ambiguous type variable `a0' in the constraint: (IsCharList a0) arising from the literal `"abc"' Probable fix: add a type signature that fixes these type variable(s) In the first argument of `length', namely `"abc"' In the first argument of `print', namely `(length "abc")' In the expression: print (length "abc") -}
Regards, Reid Barton
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Am 25.08.2013 17:13, schrieb Edward Kmett:
Looks like that takes us back to the original proposal.
It seems that both of Edward and my proposal have a drawback: Edward's proposal restricts lists to [Char]. My proposal allows more element types, but type inference fails for (length "abc"). Why is it necessary to let (length "abc") work as is? Would (length ("abc" :: String)) be too complicated?

On 25/08/13 19:29, Henning Thielemann wrote:
Am 25.08.2013 17:13, schrieb Edward Kmett:
Looks like that takes us back to the original proposal.
It seems that both of Edward and my proposal have a drawback: Edward's proposal restricts lists to [Char]. My proposal allows more element types, but type inference fails for (length "abc").
Why is it necessary to let (length "abc") work as is? Would (length ("abc" :: String)) be too complicated?
This whole proposal was motivated by the fact that the convenience extension, OverloadedStrings, makes simply things like (length "abc") inconvenient as we have to use a type signature. What you're proposing here goes completely against of why this proposal saw the light of the day to begin with. -- Mateusz K.

On Sun, Aug 25, 2013 at 2:29 PM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote:
Am 25.08.2013 17:13, schrieb Edward Kmett:
Looks like that takes us back to the original proposal.
It seems that both of Edward and my proposal have a drawback: Edward's proposal restricts lists to [Char]. My proposal allows more element types, but type inference fails for (length "abc").
Why is it necessary to let (length "abc") work as is?
The issue is that length "abc", splitAt 2 "abc", and dozens of other tools just stop working for anyone who turns on OverloadedStrings right now. These users tend to be the users who are most vulnerable from the standpoint of not knowing what is happening to them. They just see that Haskell "doesn't work" and go back to Ruby. IsString was originally put forth as a convenience to make string literals work with Text, ByteString, directly as a parsing combinator, or as a variable name or string type in an expression language, but presently that functionality comes at the tax that random other bits of code in your file stop working when you turn it on. My proposal is intended to address this fact, by giving up a subset of possible convenience instances in exchange for fixing the real headache this induces for users. I offer as an example the fact that this even bit us in lens due to the ubiquitous use of doctest throughout the package. We have to put explicit :set -XNoOverloadedStrings at the top of any $setup block that uses a string as an example, because we chose in 2-3 modules to turn on OverloadedStrings to better showcase how to work with the text and bytestring lenses. doctest per force recycles the same ghc-api session, as otherwise it takes many many times longer to run. Every once in a while someone has built a different subset of the modules in a different order, and we find out we forgot to turn it off in yet another place. The alternative is that we clutter literally a few hundred doctests with embedded :: String type annotations obscuring the very thing they were put in to teach. This was even worse before we got Simon Hengel to add support for $setup blocks! -Edward
Would (length ("abc" :: String)) be too complicated?

On Sun, Aug 25, 2013 at 05:02:10PM -0400, Edward Kmett wrote:
The issue is that length "abc", splitAt 2 "abc", and dozens of other tools just stop working for anyone who turns on OverloadedStrings right now.
Would/could this be better addressed by changing ghci/ExtendedDefaultRules such that the ambiguous uses would be defaulted to String? Thanks Ian

If that can be done in such a way that defaulting fires for FromString
(say, even without EDR turned on) it could ensure OverloadedStrings has
nearly zero impact on users.
This may not be an issue but you may need to check that just adding
FromString to the list of classes for which defaulting is done is
sufficient to make cases like (length "hello") work as unlike the other
defaulting cases, you get situations where it is partially known. e.g.
we've determined that the argument is [a], but not String. This can't
happen with the Int, Integer, (), cases, which either unify or don't.
If you're looking at hacking up that part of the compiler,
http://ghc.haskell.org/trac/ghc/ticket/8171 would also be really nice to
clean up at the same time. ;)
-Edward
On Sun, Aug 25, 2013 at 6:16 PM, Ian Lynagh
On Sun, Aug 25, 2013 at 05:02:10PM -0400, Edward Kmett wrote:
The issue is that length "abc", splitAt 2 "abc", and dozens of other
tools
just stop working for anyone who turns on OverloadedStrings right now.
Would/could this be better addressed by changing ghci/ExtendedDefaultRules such that the ambiguous uses would be defaulted to String?
Thanks Ian
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Changing the defaulting, if that is possible, would be my preference - this
way one can still use OverloadedString for list types. Disallowing them to
allow for the default case to work doesn't seem quite right, though I guess
it is acceptable if defaulting turns out to be impossible.
On Mon, Aug 26, 2013 at 1:24 AM, Edward Kmett
If that can be done in such a way that defaulting fires for FromString (say, even without EDR turned on) it could ensure OverloadedStrings has nearly zero impact on users.
This may not be an issue but you may need to check that just adding FromString to the list of classes for which defaulting is done is sufficient to make cases like (length "hello") work as unlike the other defaulting cases, you get situations where it is partially known. e.g. we've determined that the argument is [a], but not String. This can't happen with the Int, Integer, (), cases, which either unify or don't.
If you're looking at hacking up that part of the compiler, http://ghc.haskell.org/trac/ghc/ticket/8171 would also be really nice to clean up at the same time. ;)
-Edward
On Sun, Aug 25, 2013 at 6:16 PM, Ian Lynagh
wrote: On Sun, Aug 25, 2013 at 05:02:10PM -0400, Edward Kmett wrote:
The issue is that length "abc", splitAt 2 "abc", and dozens of other
tools
just stop working for anyone who turns on OverloadedStrings right now.
Would/could this be better addressed by changing ghci/ExtendedDefaultRules such that the ambiguous uses would be defaulted to String?
Thanks Ian
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

These users tend to be the users who are most vulnerable from the standpoint of not knowing what is happening to them. They just see that Haskell "doesn't work" and go back to Ruby.
(Laughing Out Loud) It is not just me then. Really I would consider taking a page out of the Ruby pragmatic playbook and recognise the importance of both monomorphic strings and overloaded strings and provide a separate syntax for either overloaded strings or good ole lists of Unicode points (to which I have an irrational sentimental attachment). Otherwise my vote is vote for the balance of the less surprises and less generality of Edward's proposal (+1). Chris

Am 25.08.2013 23:02, schrieb Edward Kmett:
The issue is that length "abc", splitAt 2 "abc", and dozens of other tools just stop working for anyone who turns on OverloadedStrings right now.
IsString was originally put forth as a convenience to make string literals work with Text, ByteString, directly as a parsing combinator, or as a variable name or string type in an expression language, but presently that functionality comes at the tax that random other bits of code in your file stop working when you turn it on.
My proposal is intended to address this fact, by giving up a subset of possible convenience instances in exchange for fixing the real headache this induces for users.
What you propose is, to let the compiler infer: "If it is something string-like (imposed by the string literal syntax in the presence of OverloadedStrings) and it is a list (imposed by 'length'), then it must be a String". This conclusion looks rather arbitrary to me. If 'length' would be more specific (e.g. Text.length) your problem would not arise. If 'length' would be more generic (e.g. Foldable.length) your proposal would not help. The problem only arises, because you want to use Prelude's list functions (_and_ OverloadedStrings _and_ don't want to write type annotations). I predict that soon people will propose here on this mailing list to replace Prelude's half-monomorphic 'length' by a fully polymorphic Foldable.length. It does not yet exist, but it could be added easily. What will you do then?

On Mon, Aug 26, 2013 at 12:33 PM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote:
I predict that soon people will propose here on this mailing list to replace Prelude's half-monomorphic 'length' by a fully polymorphic Foldable.length. It does not yet exist, but it could be added easily. What will you do then?
Nothing, because the keepers of the Prelude are allergic to such generalizations.... -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

If Ian can make defaulting work, then I'd prefer that solution. It hurts nobody and just makes everything work better. length was just the most galling example among many. The resolution to Ian's suggestion would absolutely affect just how liberal we want to be with generalizing more of the list combinators to Foldable/Traversable. There are a lot of desiderata to consider in balancing the needs of base. Forcing the only list based instance to be String is an arbitrary decision, but it fixes the vast majority of the issues with a typeclass and extension that was intended to be a convenience but currently causes a great deal of incovenience in otherwise unrelated code when you turn it on. Having base export two randomly different versions of the same combinator all over the place is also an inconvenience and fixing it comes with some tension towards OverloadedStrings. Forcing users to use signatures on every String and import Data.Traversableand Data.Foldable qualified "works," but it is the design equivalent of sticking your head in the sand and pretending their we don't have any problems. -Edward On Mon, Aug 26, 2013 at 12:33 PM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote:
Am 25.08.2013 23:02, schrieb Edward Kmett:
The issue is that length "abc", splitAt 2 "abc", and dozens of other
tools just stop working for anyone who turns on OverloadedStrings right now.
IsString was originally put forth as a convenience to make string literals work with Text, ByteString, directly as a parsing combinator, or as a variable name or string type in an expression language, but presently that functionality comes at the tax that random other bits of code in your file stop working when you turn it on.
My proposal is intended to address this fact, by giving up a subset of possible convenience instances in exchange for fixing the real headache this induces for users.
What you propose is, to let the compiler infer: "If it is something string-like (imposed by the string literal syntax in the presence of OverloadedStrings) and it is a list (imposed by 'length'), then it must be a String".
This conclusion looks rather arbitrary to me. If 'length' would be more specific (e.g. Text.length) your problem would not arise. If 'length' would be more generic (e.g. Foldable.length) your proposal would not help. The problem only arises, because you want to use Prelude's list functions (_and_ OverloadedStrings _and_ don't want to write type annotations).
I predict that soon people will propose here on this mailing list to replace Prelude's half-monomorphic 'length' by a fully polymorphic Foldable.length. It does not yet exist, but it could be added easily. What will you do then?

May I propose an alternative solution? Why not just add a syntactic way to
selectively opt in or out of `OverloadedStrings` for certain string
literals? It could be something as simple as Python's trick for prefixing
string literals with a single character to either enable or disable the
overloading:
example1 :: Int
example1 = length "Non-overloaded string"
example2 :: Parser Int
example2 = o"Overloaded string" *> pure 4
... but it doesn't have to be that specific solution. All that really
matters is that it is syntactically lightweight.
I would personally prefer "opt-in" that way you could safely turn on
`OverloadedStrings` in any module without errors and then use whatever
syntactic annotation when you want to overload a particular string.
The reason I propose this solution is that I foresee the exact same problem
occurring later on for `OverloadedLists` where you will get ambiguous type
errors any time you pass a list literal to a function of `Foldable`s.
Similarly, in that case it would also be nice to be able to selectively
opt in or out of overloaded list literals on a per-literal basis instead of
turning it on for every list literal within the module.
On Mon, Aug 26, 2013 at 9:45 AM, Edward Kmett
If Ian can make defaulting work, then I'd prefer that solution. It hurts nobody and just makes everything work better.
length was just the most galling example among many.
The resolution to Ian's suggestion would absolutely affect just how liberal we want to be with generalizing more of the list combinators to Foldable/Traversable.
There are a lot of desiderata to consider in balancing the needs of base.
Forcing the only list based instance to be String is an arbitrary decision, but it fixes the vast majority of the issues with a typeclass and extension that was intended to be a convenience but currently causes a great deal of incovenience in otherwise unrelated code when you turn it on.
Having base export two randomly different versions of the same combinator all over the place is also an inconvenience and fixing it comes with some tension towards OverloadedStrings.
Forcing users to use signatures on every String and import Data.Traversable and Data.Foldable qualified "works," but it is the design equivalent of sticking your head in the sand and pretending their we don't have any problems.
-Edward
On Mon, Aug 26, 2013 at 12:33 PM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote:
Am 25.08.2013 23:02, schrieb Edward Kmett:
The issue is that length "abc", splitAt 2 "abc", and dozens of other
tools just stop working for anyone who turns on OverloadedStrings right now.
IsString was originally put forth as a convenience to make string literals work with Text, ByteString, directly as a parsing combinator, or as a variable name or string type in an expression language, but presently that functionality comes at the tax that random other bits of code in your file stop working when you turn it on.
My proposal is intended to address this fact, by giving up a subset of possible convenience instances in exchange for fixing the real headache this induces for users.
What you propose is, to let the compiler infer: "If it is something string-like (imposed by the string literal syntax in the presence of OverloadedStrings) and it is a list (imposed by 'length'), then it must be a String".
This conclusion looks rather arbitrary to me. If 'length' would be more specific (e.g. Text.length) your problem would not arise. If 'length' would be more generic (e.g. Foldable.length) your proposal would not help. The problem only arises, because you want to use Prelude's list functions (_and_ OverloadedStrings _and_ don't want to write type annotations).
I predict that soon people will propose here on this mailing list to replace Prelude's half-monomorphic 'length' by a fully polymorphic Foldable.length. It does not yet exist, but it could be added easily. What will you do then?
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Am 26.08.2013 19:03, schrieb Gabriel Gonzalez:
May I propose an alternative solution? Why not just add a syntactic way to selectively opt in or out of `OverloadedStrings` for certain string literals? It could be something as simple as Python's trick for prefixing string literals with a single character to either enable or disable the overloading:
example1 :: Int example1 = length "Non-overloaded string"
example2 :: Parser Int example2 = o"Overloaded string" *> pure 4
... but it doesn't have to be that specific solution. All that really matters is that it is syntactically lightweight.
This "opting in" already exists: Just put a space between o and the quotation mark and define "o = fromString". It's Haskell 98. I would prefer that solution to all syntactic extension experiments.

I think Henning has a point regarding defining: o = fromString All these libraries that Edward mentions already ask the user to paste a lot of boilerplate at the top of their module consisting of various extensions and imports. Why not simply remove the `OverloadedString`s pragma from the boilerplate and replace it with `o = fromString` and get almost the exact same benefits? On Mon, Aug 26, 2013 at 10:10 AM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote:
Am 26.08.2013 19:03, schrieb Gabriel Gonzalez:
May I propose an alternative solution? Why not just add a syntactic way
to selectively opt in or out of `OverloadedStrings` for certain string literals? It could be something as simple as Python's trick for prefixing string literals with a single character to either enable or disable the overloading:
example1 :: Int example1 = length "Non-overloaded string"
example2 :: Parser Int example2 = o"Overloaded string" *> pure 4
... but it doesn't have to be that specific solution. All that really matters is that it is syntactically lightweight.
This "opting in" already exists: Just put a space between o and the quotation mark and define "o = fromString". It's Haskell 98.
I would prefer that solution to all syntactic extension experiments.

I think Henning's suggestion makes a lot of sense. It's syntactically
light-weight, requires *no* special compiler or language support, and is
quite flexible, being available per-use instead of per-module as is the
case for OverloadedStrings. The only drawback I see (and it's a moderately
big one) is that there appears to already be a lot of inertia towards
OverloadedStrings, and this would require yet another shift in the Haskell
ecosystem. That and the possibility of identifier clashes, of course...
On Mon, Aug 26, 2013 at 12:19 PM, Gabriel Gonzalez
I think Henning has a point regarding defining:
o = fromString
All these libraries that Edward mentions already ask the user to paste a lot of boilerplate at the top of their module consisting of various extensions and imports. Why not simply remove the `OverloadedString`s pragma from the boilerplate and replace it with `o = fromString` and get almost the exact same benefits?
On Mon, Aug 26, 2013 at 10:10 AM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote:
Am 26.08.2013 19:03, schrieb Gabriel Gonzalez:
May I propose an alternative solution? Why not just add a syntactic way
to selectively opt in or out of `OverloadedStrings` for certain string literals? It could be something as simple as Python's trick for prefixing string literals with a single character to either enable or disable the overloading:
example1 :: Int example1 = length "Non-overloaded string"
example2 :: Parser Int example2 = o"Overloaded string" *> pure 4
... but it doesn't have to be that specific solution. All that really matters is that it is syntactically lightweight.
This "opting in" already exists: Just put a space between o and the quotation mark and define "o = fromString". It's Haskell 98.
I would prefer that solution to all syntactic extension experiments.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On 2013-08-26 at 19:39:40 +0200, Henning Thielemann wrote:
On Mon, 26 Aug 2013, Henning Thielemann wrote:
This "opting in" already exists: Just put a space between o and the quotation mark and define "o = fromString". It's Haskell 98.
I was wrong: You even don't need the space between o and ".
it's almost perfect imho, except maybe for the minor issue that you will have to surround string literals with () or use $ sometimes, as in length (o"Overloaded String") cheers, hvr

Let's also make number literals monomorphic to Integer and provide an n ::
Num a => Integer -> a!
On Mon, Aug 26, 2013 at 9:16 PM, Herbert Valerio Riedel
On 2013-08-26 at 19:39:40 +0200, Henning Thielemann wrote:
On Mon, 26 Aug 2013, Henning Thielemann wrote:
This "opting in" already exists: Just put a space between o and the quotation mark and define "o = fromString". It's Haskell 98.
I was wrong: You even don't need the space between o and ".
it's almost perfect imho, except maybe for the minor issue that you will have to surround string literals with () or use $ sometimes, as in
length (o"Overloaded String")
cheers, hvr
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On Mon, Aug 26, 2013 at 12:30 PM, Dag Odenhall
Let's also make number literals monomorphic to Integer and provide an n :: Num a => Integer -> a!
I'm guessing this is sarcastic, but I just want to clarify what I understood Henning's proposal to be. He's not saying we should provide an `o` function in the standard library, but rather encourage users to define their own. This one liner would take the place of the current line that they devote right now to `OverloadedStrings` . However, the analogy is still apt since the exact same line of reasoning applies to overloaded numeric literals where we currently rely on defaulting to solve this problem.

On Mon, 26 Aug 2013, Gabriel Gonzalez wrote:
I'm guessing this is sarcastic, but I just want to clarify what I understood Henning's proposal to be. He's not saying we should provide an `o` function in the standard library, but rather encourage users to define their own.
Yes. I would be ok if packages provide this function, but I would urge programmers to import that explicitly.
This one liner would take the place of the current line that they devote right now to `OverloadedStrings` .
right
However, the analogy is still apt since the exact same line of reasoning applies to overloaded numeric literals where we currently rely on defaulting to solve this problem.
I always use -Wall and thus I am warned about when defaulting takes place. Thus I am confident that I do not rely on defaulting in my code.

Just to throw another curveball at this conversation, what about a general, ad-hoc solution for 'typeclass defaults'? The logic goes like this: Is there an "ambiguous type variable" error due to the use of the IsString typeclass? Try defaulting to the String instance. If that doesn't work, try defaulting to Text. Repeat for a finite, explicit list of instances. If none of these defaults are successful, type error. We have hard-coded this sort of behavior into the Num class. Why not just provide this general capability for arbitrary classes? Or at least hard-code it into IsString as well. In the absence of this sort of solution, +1 to Edward's original proposal. The "o" proposal is not viable because the oft-needed parens make it confusing and irritating to the new Haskeller. -- Dan Burton On Mon, Aug 26, 2013 at 12:41 PM, Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Mon, 26 Aug 2013, Gabriel Gonzalez wrote:
I'm guessing this is sarcastic, but I just want to clarify what I
understood Henning's proposal to be. He's not saying we should provide an `o` function in the standard library, but rather encourage users to define their own.
Yes. I would be ok if packages provide this function, but I would urge programmers to import that explicitly.
This one liner would take the place of the current line that they devote
right now to `OverloadedStrings` .
right
However, the analogy is still apt since the exact same line of reasoning
applies to overloaded numeric literals where we currently rely on defaulting to solve this problem.
I always use -Wall and thus I am warned about when defaulting takes place. Thus I am confident that I do not rely on defaulting in my code.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

ExtendedDefaultRules already provides this to some extent, for example it
makes print "hello" work without type information.
On Mon, Aug 26, 2013 at 10:09 PM, Dan Burton
Just to throw another curveball at this conversation, what about a general, ad-hoc solution for 'typeclass defaults'? The logic goes like this: Is there an "ambiguous type variable" error due to the use of the IsString typeclass? Try defaulting to the String instance. If that doesn't work, try defaulting to Text. Repeat for a finite, explicit list of instances. If none of these defaults are successful, type error.
We have hard-coded this sort of behavior into the Num class. Why not just provide this general capability for arbitrary classes? Or at least hard-code it into IsString as well.
In the absence of this sort of solution, +1 to Edward's original proposal.
The "o" proposal is not viable because the oft-needed parens make it confusing and irritating to the new Haskeller.
-- Dan Burton
On Mon, Aug 26, 2013 at 12:41 PM, Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Mon, 26 Aug 2013, Gabriel Gonzalez wrote:
I'm guessing this is sarcastic, but I just want to clarify what I
understood Henning's proposal to be. He's not saying we should provide an `o` function in the standard library, but rather encourage users to define their own.
Yes. I would be ok if packages provide this function, but I would urge programmers to import that explicitly.
This one liner would take the place of the current line that they
devote right now to `OverloadedStrings` .
right
However, the analogy is still apt since the exact same line of reasoning
applies to overloaded numeric literals where we currently rely on defaulting to solve this problem.
I always use -Wall and thus I am warned about when defaulting takes place. Thus I am confident that I do not rely on defaulting in my code.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

The problem is ExtendedDefaultRules only works when the whole type is
unknown. If we know part of the type e.g. that it is [a] for some a as we
figure out from length, or that it is (f a), then it doesn't kick in.
print works because "hello" :: (IsString a, Show a) => a
knows nothing about the argument a
and Show is included in the EDR list of blessed classes.
If at the repl you turn on OverloadedStrings and EDR
showList "hello" ""
will still blow up, because it can know you have an argument [a] with a
Show a constraint on it, and IsString [a], so it fails to meet the fairly
simplistic conditions required by EDR.
-Edward
On Mon, Aug 26, 2013 at 4:34 PM, Dag Odenhall
ExtendedDefaultRules already provides this to some extent, for example it makes print "hello" work without type information.
On Mon, Aug 26, 2013 at 10:09 PM, Dan Burton
wrote: Just to throw another curveball at this conversation, what about a general, ad-hoc solution for 'typeclass defaults'? The logic goes like this: Is there an "ambiguous type variable" error due to the use of the IsString typeclass? Try defaulting to the String instance. If that doesn't work, try defaulting to Text. Repeat for a finite, explicit list of instances. If none of these defaults are successful, type error.
We have hard-coded this sort of behavior into the Num class. Why not just provide this general capability for arbitrary classes? Or at least hard-code it into IsString as well.
In the absence of this sort of solution, +1 to Edward's original proposal.
The "o" proposal is not viable because the oft-needed parens make it confusing and irritating to the new Haskeller.
-- Dan Burton
On Mon, Aug 26, 2013 at 12:41 PM, Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Mon, 26 Aug 2013, Gabriel Gonzalez wrote:
I'm guessing this is sarcastic, but I just want to clarify what I
understood Henning's proposal to be. He's not saying we should provide an `o` function in the standard library, but rather encourage users to define their own.
Yes. I would be ok if packages provide this function, but I would urge programmers to import that explicitly.
This one liner would take the place of the current line that they
devote right now to `OverloadedStrings` .
right
However, the analogy is still apt since the exact same line of
reasoning applies to overloaded numeric literals where we currently rely on defaulting to solve this problem.
I always use -Wall and thus I am warned about when defaulting takes place. Thus I am confident that I do not rely on defaulting in my code.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Couldn't it work (with suitable extensions to the list of blessed classes) with Henning's IsCharList suggestion? The unresolved constraint would be IsCharList a. On 26/08/2013 21:47, Edward Kmett wrote:
The problem is ExtendedDefaultRules only works when the whole type is unknown. If we know part of the type e.g. that it is [a] for some a as we figure out from length, or that it is (f a), then it doesn't kick in.
print works because "hello" :: (IsString a, Show a) => a
knows nothing about the argument a
and Show is included in the EDR list of blessed classes.
If at the repl you turn on OverloadedStrings and EDR
showList "hello" ""
will still blow up, because it can know you have an argument [a] with a Show a constraint on it, and IsString [a], so it fails to meet the fairly simplistic conditions required by EDR.
-Edward
On Mon, Aug 26, 2013 at 4:34 PM, Dag Odenhall
mailto:dag.odenhall@gmail.com> wrote: |ExtendedDefaultRules| already provides this to some extent, for example it makes |print "hello"| work without type information.
On Mon, Aug 26, 2013 at 10:09 PM, Dan Burton
mailto:danburton.email@gmail.com> wrote: Just to throw another curveball at this conversation, what about a general, ad-hoc solution for 'typeclass defaults'? The logic goes like this: Is there an "ambiguous type variable" error due to the use of the IsString typeclass? Try defaulting to the String instance. If that doesn't work, try defaulting to Text. Repeat for a finite, explicit list of instances. If none of these defaults are successful, type error.
We have hard-coded this sort of behavior into the Num class. Why not just provide this general capability for arbitrary classes? Or at least hard-code it into IsString as well.
In the absence of this sort of solution, +1 to Edward's original proposal.
The "o" proposal is not viable because the oft-needed parens make it confusing and irritating to the new Haskeller.
-- Dan Burton
On Mon, Aug 26, 2013 at 12:41 PM, Henning Thielemann
mailto:lemming@henning-thielemann.de> wrote: On Mon, 26 Aug 2013, Gabriel Gonzalez wrote:
I'm guessing this is sarcastic, but I just want to clarify what I understood Henning's proposal to be. He's not saying we should provide an `o` function in the standard library, but rather encourage users to define their own.
Yes. I would be ok if packages provide this function, but I would urge programmers to import that explicitly.
This one liner would take the place of the current line that they devote right now to `OverloadedStrings` .
right
However, the analogy is still apt since the exact same line of reasoning applies to overloaded numeric literals where we currently rely on defaulting to solve this problem.
I always use -Wall and thus I am warned about when defaulting takes place. Thus I am confident that I do not rely on defaulting in my code.
_______________________________________________ Libraries mailing list Libraries@haskell.org mailto:Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org mailto:Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org mailto:Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

That seems worth pursuing.
If that works, it'd turn the defaulting rules fix from a fishing expedition
to simply adding a couple of extra classes to the list of approved basic
defaultings.
-Edward
On Mon, Aug 26, 2013 at 4:54 PM, Ganesh Sittampalam
Couldn't it work (with suitable extensions to the list of blessed classes) with Henning's IsCharList suggestion? The unresolved constraint would be IsCharList a.
On 26/08/2013 21:47, Edward Kmett wrote:
The problem is ExtendedDefaultRules only works when the whole type is unknown. If we know part of the type e.g. that it is [a] for some a as we figure out from length, or that it is (f a), then it doesn't kick in.
print works because "hello" :: (IsString a, Show a) => a
knows nothing about the argument a
and Show is included in the EDR list of blessed classes.
If at the repl you turn on OverloadedStrings and EDR
showList "hello" ""
will still blow up, because it can know you have an argument [a] with a Show a constraint on it, and IsString [a], so it fails to meet the fairly simplistic conditions required by EDR.
-Edward
On Mon, Aug 26, 2013 at 4:34 PM, Dag Odenhall
mailto:dag.odenhall@gmail.com> wrote: |ExtendedDefaultRules| already provides this to some extent, for example it makes |print "hello"| work without type information.
On Mon, Aug 26, 2013 at 10:09 PM, Dan Burton
mailto:danburton.email@gmail.com> wrote: Just to throw another curveball at this conversation, what about a general, ad-hoc solution for 'typeclass defaults'? The logic goes like this: Is there an "ambiguous type variable" error due to the use of the IsString typeclass? Try defaulting to the String instance. If that doesn't work, try defaulting to Text. Repeat for a finite, explicit list of instances. If none of these defaults are successful, type error.
We have hard-coded this sort of behavior into the Num class. Why not just provide this general capability for arbitrary classes? Or at least hard-code it into IsString as well.
In the absence of this sort of solution, +1 to Edward's original proposal.
The "o" proposal is not viable because the oft-needed parens make it confusing and irritating to the new Haskeller.
-- Dan Burton
On Mon, Aug 26, 2013 at 12:41 PM, Henning Thielemann
mailto:lemming@henning-thielemann.de> wrote: On Mon, 26 Aug 2013, Gabriel Gonzalez wrote:
I'm guessing this is sarcastic, but I just want to clarify what I understood Henning's proposal to be. He's not saying we should provide an `o` function in the standard library, but rather encourage users to define their own.
Yes. I would be ok if packages provide this function, but I would urge programmers to import that explicitly.
This one liner would take the place of the current line that they devote right now to `OverloadedStrings` .
right
However, the analogy is still apt since the exact same line of reasoning applies to overloaded numeric literals where we currently rely on defaulting to solve this problem.
I always use -Wall and thus I am warned about when defaulting takes place. Thus I am confident that I do not rely on defaulting in my code.
_______________________________________________ Libraries mailing list Libraries@haskell.org mailto:Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org mailto:Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org mailto:Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

If I understand aright, the problem is that we end up with constraints like
IsString alpha
or
IsString [beta]
where alpha or beta are otherwise-unconstrained unification variables. Under those circumstances we'd like to default to IsString String.
This is *exactly* what the current type-class-defaulting mechanism does. Eg with (show 3) you get (Show alpha, Num alpha) and want to choose alpha to be something sensible.
We've already extended it for GHCi
http://www.haskell.org/ghc/docs/latest/html/users_guide/interactive-evaluati...
I don't think this would be controversial. The path seems to be:
propose a concrete extension to the rules,
specify when it's enabled
get everyone to agree
provide a patch (relevant code is in TcSimplify.applyDefaultingRules)
Simon
| -----Original Message-----
| From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of
| Ganesh Sittampalam
| Sent: 26 August 2013 21:55
| To: Edward Kmett
| Cc: Haskell Libraries
| Subject: Re: Proposal: Improving the IsString String instance
|
| Couldn't it work (with suitable extensions to the list of blessed
| classes) with Henning's IsCharList suggestion? The unresolved constraint
| would be IsCharList a.
|
| On 26/08/2013 21:47, Edward Kmett wrote:
| > The problem is ExtendedDefaultRules only works when the whole type is
| > unknown. If we know part of the type e.g. that it is [a] for some a as
| > we figure out from length, or that it is (f a), then it doesn't kick
| in.
| >
| > print works because "hello" :: (IsString a, Show a) => a
| >
| > knows nothing about the argument a
| >
| > and Show is included in the EDR list of blessed classes.
| >
| > If at the repl you turn on OverloadedStrings and EDR
| >
| > showList "hello" ""
| >
| > will still blow up, because it can know you have an argument [a] with
| a
| > Show a constraint on it, and IsString [a], so it fails to meet the
| > fairly simplistic conditions required by EDR.
| >
| > -Edward
| >
| >
| > On Mon, Aug 26, 2013 at 4:34 PM, Dag Odenhall

We're having a hackathon here in Zurich next weekend. I'll be happy to give this a shot (or get someone attending to do it). Doesn't look too complicated. The bigger unknown are more potential build issues with GHC.
On 27 Aug 2013, at 09:27, Simon Peyton-Jones
If I understand aright, the problem is that we end up with constraints like IsString alpha or IsString [beta] where alpha or beta are otherwise-unconstrained unification variables. Under those circumstances we'd like to default to IsString String.
This is *exactly* what the current type-class-defaulting mechanism does. Eg with (show 3) you get (Show alpha, Num alpha) and want to choose alpha to be something sensible.
We've already extended it for GHCi http://www.haskell.org/ghc/docs/latest/html/users_guide/interactive-evaluati...
I don't think this would be controversial. The path seems to be: propose a concrete extension to the rules, specify when it's enabled get everyone to agree provide a patch (relevant code is in TcSimplify.applyDefaultingRules)
Simon
| -----Original Message----- | From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of | Ganesh Sittampalam | Sent: 26 August 2013 21:55 | To: Edward Kmett | Cc: Haskell Libraries | Subject: Re: Proposal: Improving the IsString String instance | | Couldn't it work (with suitable extensions to the list of blessed | classes) with Henning's IsCharList suggestion? The unresolved constraint | would be IsCharList a. | | On 26/08/2013 21:47, Edward Kmett wrote: | > The problem is ExtendedDefaultRules only works when the whole type is | > unknown. If we know part of the type e.g. that it is [a] for some a as | > we figure out from length, or that it is (f a), then it doesn't kick | in. | > | > print works because "hello" :: (IsString a, Show a) => a | > | > knows nothing about the argument a | > | > and Show is included in the EDR list of blessed classes. | > | > If at the repl you turn on OverloadedStrings and EDR | > | > showList "hello" "" | > | > will still blow up, because it can know you have an argument [a] with | a | > Show a constraint on it, and IsString [a], so it fails to meet the | > fairly simplistic conditions required by EDR. | > | > -Edward | > | > | > On Mon, Aug 26, 2013 at 4:34 PM, Dag Odenhall
mailto:dag.odenhall@gmail.com> wrote: | > | > |ExtendedDefaultRules| already provides this to some extent, for | > example it makes |print "hello"| work without type information. | > | > | > | > On Mon, Aug 26, 2013 at 10:09 PM, Dan Burton | > mailto:danburton.email@gmail.com> | wrote: | > | > Just to throw another curveball at this conversation, what | about | > a general, ad-hoc solution for 'typeclass defaults'? The logic | > goes like this: Is there an "ambiguous type variable" error | due | > to the use of the IsString typeclass? Try defaulting to the | > String instance. If that doesn't work, try defaulting to Text. | > Repeat for a finite, explicit list of instances. If none of | > these defaults are successful, type error. | > | > We have hard-coded this sort of behavior into the Num class. | Why | > not just provide this general capability for arbitrary | classes? | > Or at least hard-code it into IsString as well. | > | > In the absence of this sort of solution, +1 to Edward's | original | > proposal. | > | > The "o" proposal is not viable because the oft-needed parens | > make it confusing and irritating to the new Haskeller. | > | > -- Dan Burton | > | > | > On Mon, Aug 26, 2013 at 12:41 PM, Henning Thielemann | > mailto:lemming@henning-thielemann.de> wrote: | > | > | > On Mon, 26 Aug 2013, Gabriel Gonzalez wrote: | > | > I'm guessing this is sarcastic, but I just want to | > clarify what I understood Henning's proposal to be. | > He's not saying we should provide an `o` function in | > the standard library, but rather encourage users to | > define their own. | > | > | > Yes. I would be ok if packages provide this function, but | I | > would urge programmers to import that explicitly. | > | > | > This one liner would take the place of the current | line | > that they devote right now to `OverloadedStrings` . | > | > | > right | > | > | > However, the analogy is still apt since the exact same | > line of reasoning applies to overloaded numeric | > literals where we currently rely on defaulting to | solve | > this problem. | > | > | > I always use -Wall and thus I am warned about when | > defaulting takes place. Thus I am confident that I do not | > rely on defaulting in my code. | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org mailto:Libraries@haskell.org | > http://www.haskell.org/mailman/listinfo/libraries | > | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org mailto:Libraries@haskell.org | > http://www.haskell.org/mailman/listinfo/libraries | > | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org mailto:Libraries@haskell.org | > http://www.haskell.org/mailman/listinfo/libraries | > | > | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org | > http://www.haskell.org/mailman/listinfo/libraries | > | | | _______________________________________________ | Libraries mailing list | Libraries@haskell.org | http://www.haskell.org/mailman/listinfo/libraries _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On Tue, Aug 27, 2013 at 3:27 AM, Simon Peyton-Jones
If I understand aright, the problem is that we end up with constraints like IsString alpha or IsString [beta] where alpha or beta are otherwise-unconstrained unification variables. Under those circumstances we'd like to default to IsString String.
This is *exactly* what the current type-class-defaulting mechanism does. Eg with (show 3) you get (Show alpha, Num alpha) and want to choose alpha to be something sensible.
I may be misunderstanding you, as I thought I understood EDR pretty well. Defaulting and EDR both as I understand it look for a type variable a that only occurs in constraints of the forms (C1 a, C2 a, ..., Cn a), but Your (Show alpha, Num alpha) works because it is in that form. IsString a works, with appropriate changes to defaulting, but IsString [a] doesn't look like it would meet the condition, and my recollection from trying variations on this trick, it doesn't work in practice. That was what Ganesh's proposal was to facilitate. It ensured that we had some class in form for the (C1 a, C2 a, ..., Cn a) check. If we can get by without that, I'm 100% for it! -Edward
We've already extended it for GHCi
http://www.haskell.org/ghc/docs/latest/html/users_guide/interactive-evaluati...
I don't think this would be controversial. The path seems to be: propose a concrete extension to the rules, specify when it's enabled get everyone to agree provide a patch (relevant code is in TcSimplify.applyDefaultingRules)
Simon
| -----Original Message----- | From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of | Ganesh Sittampalam | Sent: 26 August 2013 21:55 | To: Edward Kmett | Cc: Haskell Libraries | Subject: Re: Proposal: Improving the IsString String instance | | Couldn't it work (with suitable extensions to the list of blessed | classes) with Henning's IsCharList suggestion? The unresolved constraint | would be IsCharList a. | | On 26/08/2013 21:47, Edward Kmett wrote: | > The problem is ExtendedDefaultRules only works when the whole type is | > unknown. If we know part of the type e.g. that it is [a] for some a as | > we figure out from length, or that it is (f a), then it doesn't kick | in. | > | > print works because "hello" :: (IsString a, Show a) => a | > | > knows nothing about the argument a | > | > and Show is included in the EDR list of blessed classes. | > | > If at the repl you turn on OverloadedStrings and EDR | > | > showList "hello" "" | > | > will still blow up, because it can know you have an argument [a] with | a | > Show a constraint on it, and IsString [a], so it fails to meet the | > fairly simplistic conditions required by EDR. | > | > -Edward | > | > | > On Mon, Aug 26, 2013 at 4:34 PM, Dag Odenhall
mailto:dag.odenhall@gmail.com> wrote: | > | > |ExtendedDefaultRules| already provides this to some extent, for | > example it makes |print "hello"| work without type information. | > | > | > | > On Mon, Aug 26, 2013 at 10:09 PM, Dan Burton | > mailto:danburton.email@gmail.com> | wrote: | > | > Just to throw another curveball at this conversation, what | about | > a general, ad-hoc solution for 'typeclass defaults'? The logic | > goes like this: Is there an "ambiguous type variable" error | due | > to the use of the IsString typeclass? Try defaulting to the | > String instance. If that doesn't work, try defaulting to Text. | > Repeat for a finite, explicit list of instances. If none of | > these defaults are successful, type error. | > | > We have hard-coded this sort of behavior into the Num class. | Why | > not just provide this general capability for arbitrary | classes? | > Or at least hard-code it into IsString as well. | > | > In the absence of this sort of solution, +1 to Edward's | original | > proposal. | > | > The "o" proposal is not viable because the oft-needed parens | > make it confusing and irritating to the new Haskeller. | > | > -- Dan Burton | > | > | > On Mon, Aug 26, 2013 at 12:41 PM, Henning Thielemann | > mailto:lemming@henning-thielemann.de> wrote: | > | > | > On Mon, 26 Aug 2013, Gabriel Gonzalez wrote: | > | > I'm guessing this is sarcastic, but I just want to | > clarify what I understood Henning's proposal to be. | > He's not saying we should provide an `o` function in | > the standard library, but rather encourage users to | > define their own. | > | > | > Yes. I would be ok if packages provide this function, but | I | > would urge programmers to import that explicitly. | > | > | > This one liner would take the place of the current | line | > that they devote right now to `OverloadedStrings` . | > | > | > right | > | > | > However, the analogy is still apt since the exact same | > line of reasoning applies to overloaded numeric | > literals where we currently rely on defaulting to | solve | > this problem. | > | > | > I always use -Wall and thus I am warned about when | > defaulting takes place. Thus I am confident that I do not | > rely on defaulting in my code. | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org mailto:Libraries@haskell.org | > http://www.haskell.org/mailman/listinfo/libraries | > | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org mailto:Libraries@haskell.org | > http://www.haskell.org/mailman/listinfo/libraries | > | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org mailto:Libraries@haskell.org | > http://www.haskell.org/mailman/listinfo/libraries | > | > | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org | > http://www.haskell.org/mailman/listinfo/libraries | > | | | _______________________________________________ | Libraries mailing list | Libraries@haskell.org | http://www.haskell.org/mailman/listinfo/libraries

Yes, extending the defaulting rule to cover IsString would mean weakening the condition that all the constraints are of form (C a) where a is a type variable. That’s ok; the whole defaulting rule is, necessarily, rather ad-hoc. It just needs to be precisely specified.
Simon
From: Edward Kmett [mailto:ekmett@gmail.com]
Sent: 28 August 2013 04:19
To: Simon Peyton-Jones
Cc: Ganesh Sittampalam; Haskell Libraries
Subject: Re: Proposal: Improving the IsString String instance
On Tue, Aug 27, 2013 at 3:27 AM, Simon Peyton-Jones

PS: I'm not convinced that it's worth the overhead of adding a new class. Modifying the defaulting rules would probably be enough, although it does involve one new feature, namely that it must default IsString [beta] as well as IsString alpha.
Simon
| -----Original Message-----
| From: Simon Peyton-Jones
| Sent: 27 August 2013 08:27
| To: 'Ganesh Sittampalam'; Edward Kmett
| Cc: Haskell Libraries
| Subject: RE: Proposal: Improving the IsString String instance
|
| If I understand aright, the problem is that we end up with constraints
| like
| IsString alpha
| or
| IsString [beta]
| where alpha or beta are otherwise-unconstrained unification variables.
| Under those circumstances we'd like to default to IsString String.
|
| This is *exactly* what the current type-class-defaulting mechanism does.
| Eg with (show 3) you get (Show alpha, Num alpha) and want to choose
| alpha to be something sensible.
|
| We've already extended it for GHCi
| http://www.haskell.org/ghc/docs/latest/html/users_guide/interactive-
| evaluation.html#extended-default-rules
|
| I don't think this would be controversial. The path seems to be:
| propose a concrete extension to the rules,
| specify when it's enabled
| get everyone to agree
| provide a patch (relevant code is in
| TcSimplify.applyDefaultingRules)
|
| Simon
|
| | -----Original Message-----
| | From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of
| | Ganesh Sittampalam
| | Sent: 26 August 2013 21:55
| | To: Edward Kmett
| | Cc: Haskell Libraries
| | Subject: Re: Proposal: Improving the IsString String instance
| |
| | Couldn't it work (with suitable extensions to the list of blessed
| | classes) with Henning's IsCharList suggestion? The unresolved
| constraint
| | would be IsCharList a.
| |
| | On 26/08/2013 21:47, Edward Kmett wrote:
| | > The problem is ExtendedDefaultRules only works when the whole type
| is
| | > unknown. If we know part of the type e.g. that it is [a] for some a
| as
| | > we figure out from length, or that it is (f a), then it doesn't kick
| | in.
| | >
| | > print works because "hello" :: (IsString a, Show a) => a
| | >
| | > knows nothing about the argument a
| | >
| | > and Show is included in the EDR list of blessed classes.
| | >
| | > If at the repl you turn on OverloadedStrings and EDR
| | >
| | > showList "hello" ""
| | >
| | > will still blow up, because it can know you have an argument [a]
| with
| | a
| | > Show a constraint on it, and IsString [a], so it fails to meet the
| | > fairly simplistic conditions required by EDR.
| | >
| | > -Edward
| | >
| | >
| | > On Mon, Aug 26, 2013 at 4:34 PM, Dag Odenhall
|

I'd be marginally in favour of the new class + simpler defaulting rule. This is mostly on the philosophical ground that it's better to compose existing features than to introduce new ones. It also feels like it might be more future-proof/flexible, though I can't think of a compelling example. A weak one is that someone might want to work with Array Char or similar. On 27/08/2013 08:29, Simon Peyton-Jones wrote:
PS: I'm not convinced that it's worth the overhead of adding a new class. Modifying the defaulting rules would probably be enough, although it does involve one new feature, namely that it must default IsString [beta] as well as IsString alpha.
Simon
| -----Original Message----- | From: Simon Peyton-Jones | Sent: 27 August 2013 08:27 | To: 'Ganesh Sittampalam'; Edward Kmett | Cc: Haskell Libraries | Subject: RE: Proposal: Improving the IsString String instance | | If I understand aright, the problem is that we end up with constraints | like | IsString alpha | or | IsString [beta] | where alpha or beta are otherwise-unconstrained unification variables. | Under those circumstances we'd like to default to IsString String. | | This is *exactly* what the current type-class-defaulting mechanism does. | Eg with (show 3) you get (Show alpha, Num alpha) and want to choose | alpha to be something sensible. | | We've already extended it for GHCi | http://www.haskell.org/ghc/docs/latest/html/users_guide/interactive- | evaluation.html#extended-default-rules | | I don't think this would be controversial. The path seems to be: | propose a concrete extension to the rules, | specify when it's enabled | get everyone to agree | provide a patch (relevant code is in | TcSimplify.applyDefaultingRules) | | Simon | | | -----Original Message----- | | From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of | | Ganesh Sittampalam | | Sent: 26 August 2013 21:55 | | To: Edward Kmett | | Cc: Haskell Libraries | | Subject: Re: Proposal: Improving the IsString String instance | | | | Couldn't it work (with suitable extensions to the list of blessed | | classes) with Henning's IsCharList suggestion? The unresolved | constraint | | would be IsCharList a. | | | | On 26/08/2013 21:47, Edward Kmett wrote: | | > The problem is ExtendedDefaultRules only works when the whole type | is | | > unknown. If we know part of the type e.g. that it is [a] for some a | as | | > we figure out from length, or that it is (f a), then it doesn't kick | | in. | | > | | > print works because "hello" :: (IsString a, Show a) => a | | > | | > knows nothing about the argument a | | > | | > and Show is included in the EDR list of blessed classes. | | > | | > If at the repl you turn on OverloadedStrings and EDR | | > | | > showList "hello" "" | | > | | > will still blow up, because it can know you have an argument [a] | with | | a | | > Show a constraint on it, and IsString [a], so it fails to meet the | | > fairly simplistic conditions required by EDR. | | > | | > -Edward | | > | | > | | > On Mon, Aug 26, 2013 at 4:34 PM, Dag Odenhall |
mailto:dag.odenhall@gmail.com> wrote: | | > | | > |ExtendedDefaultRules| already provides this to some extent, for | | > example it makes |print "hello"| work without type information. | | > | | > | | > | | > On Mon, Aug 26, 2013 at 10:09 PM, Dan Burton | | > mailto:danburton.email@gmail.com> | | wrote: | | > | | > Just to throw another curveball at this conversation, what | | about | | > a general, ad-hoc solution for 'typeclass defaults'? The | logic | | > goes like this: Is there an "ambiguous type variable" error | | due | | > to the use of the IsString typeclass? Try defaulting to the | | > String instance. If that doesn't work, try defaulting to | Text. | | > Repeat for a finite, explicit list of instances. If none of | | > these defaults are successful, type error. | | > | | > We have hard-coded this sort of behavior into the Num class. | | Why | | > not just provide this general capability for arbitrary | | classes? | | > Or at least hard-code it into IsString as well. | | > | | > In the absence of this sort of solution, +1 to Edward's | | original | | > proposal. | | > | | > The "o" proposal is not viable because the oft-needed parens | | > make it confusing and irritating to the new Haskeller. | | > | | > -- Dan Burton | | > | | > | | > On Mon, Aug 26, 2013 at 12:41 PM, Henning Thielemann | | > mailto:lemming@henning-thielemann.de> wrote: | | > | | > | | > On Mon, 26 Aug 2013, Gabriel Gonzalez wrote: | | > | | > I'm guessing this is sarcastic, but I just want to | | > clarify what I understood Henning's proposal to be. | | > He's not saying we should provide an `o` function | in | | > the standard library, but rather encourage users to | | > define their own. | | > | | > | | > Yes. I would be ok if packages provide this function, | but | | I | | > would urge programmers to import that explicitly. | | > | | > | | > This one liner would take the place of the current | | line | | > that they devote right now to `OverloadedStrings` . | | > | | > | | > right | | > | | > | | > However, the analogy is still apt since the exact | same | | > line of reasoning applies to overloaded numeric | | > literals where we currently rely on defaulting to | | solve | | > this problem. | | > | | > | | > I always use -Wall and thus I am warned about when | | > defaulting takes place. Thus I am confident that I do | not | | > rely on defaulting in my code. | | > | | > _______________________________________________ | | > Libraries mailing list | | > Libraries@haskell.org mailto:Libraries@haskell.org | | > http://www.haskell.org/mailman/listinfo/libraries | | > | | > | | > | | > _______________________________________________ | | > Libraries mailing list | | > Libraries@haskell.org mailto:Libraries@haskell.org | | > http://www.haskell.org/mailman/listinfo/libraries | | > | | > | | > | | > _______________________________________________ | | > Libraries mailing list | | > Libraries@haskell.org mailto:Libraries@haskell.org | | > http://www.haskell.org/mailman/listinfo/libraries | | > | | > | | > | | > | | > _______________________________________________ | | > Libraries mailing list | | > Libraries@haskell.org | | > http://www.haskell.org/mailman/listinfo/libraries | | > | | | | | | _______________________________________________ | | Libraries mailing list | | Libraries@haskell.org | | http://www.haskell.org/mailman/listinfo/libraries _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

I took a stab at implementing this. Having a superclass would probably make the implementation simpler.
I can't figure out the proper way to add a "C [a] = <ty>" constraint to the simplifier. The defaulting mechanism currently just looks tries combinations of "a := <ty>" for all the candidate types. If "a" is not just a type variable this needs to be add another wanted constraint, but I couldn't find a function that satisfies that purpose. (Even though I read the OutsideIn(X) journal paper a while ago, the type checker code does indeed seem nearly impenetrable -- there's still some boxy unification code in TcUnify, and it's not clear how that interacts with the new solver.)
Anyway, if someone can point out how I to turn "setWantedTyBind tv ty" into something like "setWantedEquality ty1 ty2" I can implement it. Otherwise, I'd have to use use some rather gnarly hack that special-cases "C [a] = <ty>" to "a := Char" iff "<ty> == String"
/ Thomas
On 29 Aug 2013, at 08:03, Ganesh Sittampalam
I'd be marginally in favour of the new class + simpler defaulting rule.
This is mostly on the philosophical ground that it's better to compose existing features than to introduce new ones.
It also feels like it might be more future-proof/flexible, though I can't think of a compelling example. A weak one is that someone might want to work with Array Char or similar.
On 27/08/2013 08:29, Simon Peyton-Jones wrote:
PS: I'm not convinced that it's worth the overhead of adding a new class. Modifying the defaulting rules would probably be enough, although it does involve one new feature, namely that it must default IsString [beta] as well as IsString alpha.
Simon
| -----Original Message----- | From: Simon Peyton-Jones | Sent: 27 August 2013 08:27 | To: 'Ganesh Sittampalam'; Edward Kmett | Cc: Haskell Libraries | Subject: RE: Proposal: Improving the IsString String instance | | If I understand aright, the problem is that we end up with constraints | like | IsString alpha | or | IsString [beta] | where alpha or beta are otherwise-unconstrained unification variables. | Under those circumstances we'd like to default to IsString String. | | This is *exactly* what the current type-class-defaulting mechanism does. | Eg with (show 3) you get (Show alpha, Num alpha) and want to choose | alpha to be something sensible. | | We've already extended it for GHCi | http://www.haskell.org/ghc/docs/latest/html/users_guide/interactive- | evaluation.html#extended-default-rules | | I don't think this would be controversial. The path seems to be: | propose a concrete extension to the rules, | specify when it's enabled | get everyone to agree | provide a patch (relevant code is in | TcSimplify.applyDefaultingRules) | | Simon | | | -----Original Message----- | | From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of | | Ganesh Sittampalam | | Sent: 26 August 2013 21:55 | | To: Edward Kmett | | Cc: Haskell Libraries | | Subject: Re: Proposal: Improving the IsString String instance | | | | Couldn't it work (with suitable extensions to the list of blessed | | classes) with Henning's IsCharList suggestion? The unresolved | constraint | | would be IsCharList a. | | | | On 26/08/2013 21:47, Edward Kmett wrote: | | > The problem is ExtendedDefaultRules only works when the whole type | is | | > unknown. If we know part of the type e.g. that it is [a] for some a | as | | > we figure out from length, or that it is (f a), then it doesn't kick | | in. | | > | | > print works because "hello" :: (IsString a, Show a) => a | | > | | > knows nothing about the argument a | | > | | > and Show is included in the EDR list of blessed classes. | | > | | > If at the repl you turn on OverloadedStrings and EDR | | > | | > showList "hello" "" | | > | | > will still blow up, because it can know you have an argument [a] | with | | a | | > Show a constraint on it, and IsString [a], so it fails to meet the | | > fairly simplistic conditions required by EDR. | | > | | > -Edward | | > | | > | | > On Mon, Aug 26, 2013 at 4:34 PM, Dag Odenhall |
mailto:dag.odenhall@gmail.com> wrote: | | > | | > |ExtendedDefaultRules| already provides this to some extent, for | | > example it makes |print "hello"| work without type information. | | > | | > | | > | | > On Mon, Aug 26, 2013 at 10:09 PM, Dan Burton | | > mailto:danburton.email@gmail.com> | | wrote: | | > | | > Just to throw another curveball at this conversation, what | | about | | > a general, ad-hoc solution for 'typeclass defaults'? The | logic | | > goes like this: Is there an "ambiguous type variable" error | | due | | > to the use of the IsString typeclass? Try defaulting to the | | > String instance. If that doesn't work, try defaulting to | Text. | | > Repeat for a finite, explicit list of instances. If none of | | > these defaults are successful, type error. | | > | | > We have hard-coded this sort of behavior into the Num class. | | Why | | > not just provide this general capability for arbitrary | | classes? | | > Or at least hard-code it into IsString as well. | | > | | > In the absence of this sort of solution, +1 to Edward's | | original | | > proposal. | | > | | > The "o" proposal is not viable because the oft-needed parens | | > make it confusing and irritating to the new Haskeller. | | > | | > -- Dan Burton | | > | | > | | > On Mon, Aug 26, 2013 at 12:41 PM, Henning Thielemann | | > mailto:lemming@henning-thielemann.de> wrote: | | > | | > | | > On Mon, 26 Aug 2013, Gabriel Gonzalez wrote: | | > | | > I'm guessing this is sarcastic, but I just want to | | > clarify what I understood Henning's proposal to be. | | > He's not saying we should provide an `o` function | in | | > the standard library, but rather encourage users to | | > define their own. | | > | | > | | > Yes. I would be ok if packages provide this function, | but | | I | | > would urge programmers to import that explicitly. | | > | | > | | > This one liner would take the place of the current | | line | | > that they devote right now to `OverloadedStrings` . | | > | | > | | > right | | > | | > | | > However, the analogy is still apt since the exact | same | | > line of reasoning applies to overloaded numeric | | > literals where we currently rely on defaulting to | | solve | | > this problem. | | > | | > | | > I always use -Wall and thus I am warned about when | | > defaulting takes place. Thus I am confident that I do | not | | > rely on defaulting in my code. | | > | | > _______________________________________________ | | > Libraries mailing list | | > Libraries@haskell.org mailto:Libraries@haskell.org | | > http://www.haskell.org/mailman/listinfo/libraries | | > | | > | | > | | > _______________________________________________ | | > Libraries mailing list | | > Libraries@haskell.org mailto:Libraries@haskell.org | | > http://www.haskell.org/mailman/listinfo/libraries | | > | | > | | > | | > _______________________________________________ | | > Libraries mailing list | | > Libraries@haskell.org mailto:Libraries@haskell.org | | > http://www.haskell.org/mailman/listinfo/libraries | | > | | > | | > | | > | | > _______________________________________________ | | > Libraries mailing list | | > Libraries@haskell.org | | > http://www.haskell.org/mailman/listinfo/libraries | | > | | | | | | _______________________________________________ | | Libraries mailing list | | Libraries@haskell.org | | http://www.haskell.org/mailman/listinfo/libraries _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

No need, they don't have the problem that started this thread. They
default to Integer.
Erik
On Mon, Aug 26, 2013 at 9:30 PM, Dag Odenhall
Let's also make number literals monomorphic to Integer and provide an n :: Num a => Integer -> a!
On Mon, Aug 26, 2013 at 9:16 PM, Herbert Valerio Riedel
wrote: On 2013-08-26 at 19:39:40 +0200, Henning Thielemann wrote:
On Mon, 26 Aug 2013, Henning Thielemann wrote:
This "opting in" already exists: Just put a space between o and the quotation mark and define "o = fromString". It's Haskell 98.
I was wrong: You even don't need the space between o and ".
it's almost perfect imho, except maybe for the minor issue that you will have to surround string literals with () or use $ sometimes, as in
length (o"Overloaded String")
cheers, hvr
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

The argument in favor of using some 'o' combinator works even better on my side of the debate. ;) I can coopt the suggestion of 'o' to say that you can use it for the few instances of IsString [Foo] that you want without having to say that the solution to this problem is to not fix it and make everyone pay this price. It is clear that other portions of the community found o"foo" an unacceptable tax for their EDSLs, so all you're saying is that this problem doesn't affect you. The web frameworks won't stop using OverloadedStrings, and I don't in general think they should have to. I'm not making a moral stance for changing it or not changing it, merely a pragmatic one. So we have 3 options. 1) make the change, 2) fix defaulting somehow to cover IsString 3) do nothing. Out of these I prefer option 2 to option 1, and find that option 3 doesn't lead to an acceptable outcome. Option 1 has knock-on effects and is less powerful than option 2 in that it would interact more poorly with the proposed Foldable/Traversable changes. All of that said, I am concerned that we'll now paralyze because of Ian's dangled option that we may be able to solve it with improved defaulting rules, as he has indicated a lack of desire to go implement that possible solution. Personally, and not speaking in any official capacity, I'd be willing to punt the issue out to say, something like 7.10 with the caveat that if by then we haven't resolved the defaulting solution by then we should implement this. That way we start the generalization of Foldable/Traversable in 7.9, and it gives us a year or so for someone to figure out if the defaulting solution can work, and the current proposal can serve as a fallback position. I don't know about Snoyman or Doug's stance on the urgency of the issue as it affects users far more in their spheres of influence than mine, so if they preferred to bull ahead I'd be apt to defer to them. -Edward On Mon, Aug 26, 2013 at 1:39 PM, Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Mon, 26 Aug 2013, Henning Thielemann wrote:
This "opting in" already exists: Just put a space between o and the
quotation mark and define "o = fromString". It's Haskell 98.
I was wrong: You even don't need the space between o and ".

On Mon, Aug 26, 2013 at 04:41:43PM -0400, Edward Kmett wrote:
The argument in favor of using some 'o' combinator works even better on my side of the debate. ;)
I can coopt the suggestion of 'o' to say that you can use it for the few instances of IsString [Foo] that you want
But under your proposal (assuming you mean the original proposal), there wouldn't be an IsString [Foo] instance, would there? So o = fromString wouldn't work for [Foo]? Thanks Ian

What i mean is that, there are a few users like Oren who have written
instances like
instance IsString [String] for parsing dotted quads or what have you.
those would be the kinds of thing that would become o :: String ->
[String], the stuff that couldn't be implemented without overlapping the a
~ Char => IsString [a] instance.
That said, I think Ganesh's proposal should work, so its moot.
-Edward
On Mon, Aug 26, 2013 at 5:18 PM, Ian Lynagh
On Mon, Aug 26, 2013 at 04:41:43PM -0400, Edward Kmett wrote:
The argument in favor of using some 'o' combinator works even better on my side of the debate. ;)
I can coopt the suggestion of 'o' to say that you can use it for the few instances of IsString [Foo] that you want
But under your proposal (assuming you mean the original proposal), there wouldn't be an IsString [Foo] instance, would there? So o = fromString wouldn't work for [Foo]?
Thanks Ian
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On Mon, Aug 26, 2013 at 12:45:31PM -0400, Edward Kmett wrote:
If Ian can make defaulting work, then I'd prefer that solution.
I'm not planning on implementing it myself any time soon, but I don't think the libraries should be changed if changing defaulting instead would be both feasible and better.
On Mon, Aug 26, 2013 at 12:33 PM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote:
What you propose is, to let the compiler infer: "If it is something string-like (imposed by the string literal syntax in the presence of OverloadedStrings) and it is a list (imposed by 'length'), then it must be a String".
To clarify, I was thinking of something more like appending String to the default defaulting list, and IsString to the list of classes that trigger defaulting. I'm not sure OTTOMH if String actually being [Char] causes any problems. Thanks Ian

Am 26.08.2013 18:45, schrieb Edward Kmett:
Forcing users to use signatures on every Stringand import Data.Traversableand Data.Foldablequalified "works," but it is the design equivalent of sticking your head in the sand and pretending their we don't have any problems.
Actually, I would not use type annotations. Instead I would avoid OverloadedStrings and write Text.pack where necessary. This saves me OverloadedStrings, the special list instance for IsString and type annotations. Maybe after all attempts of extending the compiler and patching the libraries we find that the initial solution was the best one.

I don't think every web framework in the Haskell ecosystem is about to adopt this practice, so that doesn't actually solve the problem, it merely says the problem doesn't affect you. On Mon, Aug 26, 2013 at 1:07 PM, Henning Thielemann < schlepptop@henning-thielemann.de> wrote:
Am 26.08.2013 18:45, schrieb Edward Kmett:
Forcing users to use signatures on every Stringand import
Data.Traversableand Data.Foldablequalified "works," but it is the design
equivalent of sticking your head in the sand and pretending their we don't have any problems.
Actually, I would not use type annotations. Instead I would avoid OverloadedStrings and write Text.pack where necessary. This saves me OverloadedStrings, the special list instance for IsString and type annotations. Maybe after all attempts of extending the compiler and patching the libraries we find that the initial solution was the best one.
participants (24)
-
Brandon Allbery
-
Chris Dornan
-
Christopher Done
-
Dag Odenhall
-
Dan Burton
-
Edward Kmett
-
Erik Hesselink
-
Gabriel Gonzalez
-
Ganesh Sittampalam
-
Henning Thielemann
-
Henning Thielemann
-
Herbert Valerio Riedel
-
Ian Lynagh
-
Ivan Lazar Miljenovic
-
John Lato
-
John Wiegley
-
Mateusz Kowalczyk
-
Michael Sloan
-
Michael Snoyman
-
Oren Ben-Kiki
-
Reid Barton
-
Simon Peyton-Jones
-
Sjoerd Visscher
-
Thomas Schilling