Ticket #6030 (new feature request)

Opened 13 months ago

Last modified 13 months ago

Typeclass constraint should pick the OverloadedString type.

Reported by: GregWeber Owned by:
Priority: normal Milestone: _|_
Component: Compiler Version: 7.4.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: None/Unknown Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

{-# LANGUAGE OverloadedStrings #-}
import Data.Text as T

class    NoDefault a      where noDefault :: a -> Text
instance NoDefault T.Text where noDefault = id

main = print (noDefault "Hello!")
default.hs:7:15:
    Ambiguous type variable `a0' in the constraints:
      (NoDefault a0) arising from a use of `noDefault'
                     at default.hs:7:15-23
      (Data.String.IsString a0) arising from the literal `"Hello!"'
                                at default.hs:7:25-32
    Probable fix: add a type signature that fixes these type variable(s)
    In the first argument of `print', namely `(noDefault "Hello!")'
    In the expression: print (noDefault "Hello!")
    In an equation for `main': main = print (noDefault "Hello!")

Change History

Changed 13 months ago by michalt

I don't really see a problem/bug here. The type is ambiguous and according to documentation the defaulting mechanism (IIRC to String) will not work here:

The standard defaulting rule (Haskell Report, Section 4.3.4) is extended thus: defaulting applies when all the unresolved constraints involve standard classes or IsString?; and at least one is a numeric class or IsString?.

So it's like writing:

module Main where

class Foo a where
  foo :: a -> ()

main = print (foo $ 0)

which results in

[1 of 1] Compiling Main             ( Test.hs, interpreted )

Test.hs:6:21:
    Ambiguous type variable `a0' in the constraints:
      (Num a0) arising from the literal `0' at Test.hs:6:21
      (Foo a0) arising from a use of `foo' at Test.hs:6:15-17
    Probable fix: add a type signature that fixes these type variable(s)
    In the second argument of `($)', namely `0'
    In the first argument of `print', namely `(foo $ 0)'
    In the expression: print (foo $ 0)
Failed, modules loaded: none.

Am I missing something?

Changed 13 months ago by GregWeber

Your example is very different for mine: it is missing a numeric instance. If the current behavior is properly documented now, consider this ticket a feature request.

Changed 13 months ago by simonpj

  • difficulty set to Unknown

In that case, perhaps you can turn it into a feature request? That would mean

  • reading the current specification (pointed to above),
  • proposing a concrete change to the language specification, and
  • reflecting on what consequences that might have for others.

Thanks.

Changed 13 months ago by GregWeber

  • type changed from bug to feature request

ok, changed to a feature request. I am not smart enough to know what the consequences are for others: I was hoping that would be more obvious to those that work on the type system. I was just trying to write a program to be convenient for users and GHC would not allow me to, which makes me sad :(

I suspect this issue has not been brought up because generally one would write the typeclass for multiple IsString? instances. The undocumented defaulting capability, while putting a little extra burden on the users, seems generally a more powerful approach. So maybe after I can add documentation for defaulting I will close this.

Changed 13 months ago by simonpj

Maybe you can do the first two bullets even if you don't feel competent for the third?

Changed 13 months ago by GregWeber

ExtendedDefaultRules? is good but not fully covering my use cases of data types built of IsString?, so I am still very interested in proposing something here or improving ExtendedDefaultRules?. The following does not compile:

{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ExtendedDefaultRules #-}
{-# LANGUAGE FlexibleInstances #-}
module Default (noDefault) where
import Data.Text as T
default (T.Text)

class    NoDefault a        where noDefault :: a -> [Text]
instance NoDefault [T.Text] where noDefault = id

main = print (noDefault ["Hello!"])

Changed 13 months ago by simonpj

  • milestone set to _|_

There is quite a bit of discussion on the ghc-users list about this. I'm going to park this ticket until someone emerges with a concrete proposal.

Simon

Changed 13 months ago by GregWeber

The discussion on the ghc-users thread veered off on another course. The ticket here still represents the original issues. In particular, I can't build up data structures with ExtendedDefaultRules?. defaulting is actually different than what I opened the original ticket for: should I open a different ticket?

Note: See TracTickets for help on using tickets.