Opened 4 years ago

Closed 4 years ago

#5673 closed bug (duplicate)

GHCi ignores {-# LANGUAGE OverloadedStrings #-}

Reported by: erikd Owned by:
Priority: normal Milestone:
Component: GHCi Version: 7.0.4
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Other Test Case:
Blocked By: Blocking:
Related Tickets: Differential Revisions:

Description

Very simple test file like:

{-# LANGUAGE OverloadedStrings #-}

import Data.ByteString                     (ByteString)
import qualified Data.ByteString.Char8     as BS

newlineCount :: ByteString -> Int
newlineCount bs = BS.foldl foldFun 0 bs
   where foldFun s ch = if ch == '\n' then s + 1 else s

main :: IO ()
main = print $ newlineCount "a\nb\nc\n"

If I load this into GHCi, I can run the main function, but if I try to run newlineCount with a string I provide, I get an error:

erikd@pharoah > ghci test.hs 
GHCi, version 7.0.4: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main             ( test.hs, interpreted )
Ok, modules loaded: Main.
*Main> main
Loading package bytestring-0.9.1.10 ... linking ... done.
3
*Main> newlineCount "a\nb\nc\n"

<interactive>:1:14:
    Couldn't match expected type `ByteString' with actual type `[Char]'
    In the first argument of `newlineCount', namely `"a\nb\nc\n"'
    In the expression: newlineCount "a\nb\nc\n"
    In an equation for `it': it = newlineCount "a\nb\nc\n"

which is rather unexpected.

Change History (8)

comment:1 Changed 4 years ago by michalt

  • Resolution set to invalid
  • Status changed from new to closed

I think the pragma only refers to the code in the file and not to what you write in the ghci prompt. You can use -XOverloadedStrings to make it work:

> ghci -XOverloadedStrings Test.hs
GHCi, version 7.2.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
[1 of 1] Compiling Main             ( Test.hs, interpreted )
Ok, modules loaded: Main.
*Main> newlineCount "a\nb\nc\n"
Loading package bytestring-0.9.2.0 ... linking ... done.
3
*Main>

So I don't think there's any bug/problem here (please reopen if you don't agree).

comment:2 Changed 4 years ago by nomeata

  • Resolution invalid deleted
  • Status changed from closed to new

I agree with erikd here. The documentation says

GHCi has loaded the Main module, and the prompt has changed to “*Main>” to indicate that the current context for expressions typed at the prompt is the Main module we just loaded.

so it can be expected that code entered at the ghci prompt behaves as if it were put in the loaded module.

With the new support for top-level-declarations in ghci, this issue will also arise with the numerous pragmas affecting type classes. (Reopening as advised by michalt)

comment:3 Changed 4 years ago by erikd

I agree with momeata.

My main problem with this is the element of surprise; the main function works correctly while calling newlineCount doesn't.

Even Haskell beginners are being told that in most cases ByteString or Text should be chosen over String. They are also encouraged to try things out in GHCi. This behavior will confound and confuse them. It certainly did that for me and I've although I'm not anywhere near a Haskell expert I have been using Haskell for many years.

comment:4 follow-up: Changed 4 years ago by simonpj

So I think the feature request is this:

  • When GHCi displays a prompt for *M>, any LANGUAGE pramas in module M should be in force at the prompt.

Is that it? That's a reasonable suggestion, bu there are some obvious design questions:

  • What if multiple modules are in scope at the prompt? Do we union their language pragmas? What if they contradict each other (eg one has OverloadedStrings and one has NoOverloadedStrings (admittedly unusual))?
  • Should this apply for modules in scope with all their bindings *M>, or also for export-only ones M>. (I lean the former.)
  • What if you say :set MultiParamTypeClasses. Does that apply regardless of what modules are in scope? (Probably yes.)

I think there are probably resonable answers to these questions, but there is a bit of design work to do. I wonder if there are other wrinkles I have not thought of.

There would be some implementation work too; I think we don't currently remember which flags were added as language pragmas on a per-module basis.

comment:5 in reply to: ↑ 4 Changed 4 years ago by nomeata

Hi,

only answering those questions that I can, for the others it is “dunno” (and partly “duncare” (not to be confused with “duncan”, which if written capitalized, is a very able one, despite the name)).

Replying to simonpj:

So I think the feature request is this:

  • When GHCi displays a prompt for *M>, any LANGUAGE pramas in module M should be in force at the prompt.

Is that it?

Yes, this is the core of the issue.

That's a reasonable suggestion, bu there are some obvious design questions:

  • Should this apply for modules in scope with all their bindings *M>, or also for export-only ones M>. (I lean the former.)

I fully agree; for export-only modules, I have the “user” view, not the “inside-module view”.

Greetings, Joachim

comment:6 Changed 4 years ago by erikd

Excellent post on the haskell-cafe mailing list by Bas van Dijk :

I think it's very dangerous if language extensions "leak" from modules
by default. For example if someone creates a library and needs to use
some unsafe language extensions like:

{-# LANGUAGE UndecidableInstances, OverlappingInstances, IncoherentInstances #-}
module SomeLib where ...

You surely don't want to silently enable these in some unsuspecting client:

module MyFirstHaskellModule where
import SomeLib
...

I can imagine having a pragma for explicitly exporting language extensions:

{-# EXPORT_LANGUAGE OverloadedStrings #-}

comment:7 Changed 4 years ago by simonmar

I'd just like to point out that we've gone over most of this ground at least once before, and there's a proposed set of changes here: http://hackage.haskell.org/trac/ghc/ticket/3217#comment:15. I still stand by that proposal, it addresses all the issues raised above.

The only possible downside is that you would no longer be able to say :module *A *B (i.e. have multiple modules "fully open" at the prompt), but I doubt anyone really needs to do this.

comment:8 Changed 4 years ago by simonpj

  • Resolution set to duplicate
  • Status changed from new to closed

Goog point! I'd forgotten all about that. Closing as duplicate, with a cross ref.

Note: See TracTickets for help on using tickets.