1

So my questions are:

1) (This is more specific and related to the problem I had) How can I know the default types for numbers, i.e., the Ts in default (T1, ...) being used at the moment in GHCi?

2) Is there a way to make typed code and loaded code behave the same always in GHCi? (excluding the differences related to the fact that typed code is run inside the IO Monad) For example, I should not have to include some kind of extension (e.g., ExtendedDefaultRules) so that the code in a file runs exactly as run in the prompt.

3) How can I invoke GHC and GHCi so that the same code shows the same behavior whether run via GHC or GHCi? (imagine I load the main file of an app and type run main in GHCi)

Thanks

Cubic
  • 14,902
  • 5
  • 47
  • 92
mljrg
  • 4,430
  • 2
  • 36
  • 49
  • 1
    See the end of https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/ghci-set.html#ghci-interactive-options and the sections linked from there. – Reid Barton Sep 17 '15 at 18:51
  • 2
    I don't think it's possible to make the monomorphism restriction work right in GHCi, because the type of an expression can't be inferred based on things the interpreter has not yet seen. So you'll need to use `NoMonomorphismRestriction` or whatever it's called in your files. – dfeuer Sep 17 '15 at 18:56
  • @dfeuer I am using 7.10.2 so that restriction does not apply. But nice to know that. – mljrg Sep 17 '15 at 22:32
  • The monomorphism restriction certainly applies in files, even in 7.10.2. – Ørjan Johansen Sep 17 '15 at 22:42
  • @ØrjanJohansen Nice to know, but why such difference? Why is not turned off also for files? From reading RWH book it seems that is something that will be removed? Why has it not been removed yet? Need clarifications here. – mljrg Sep 18 '15 at 10:15
  • @mljrg GHCi turning it off is just for convenience, while changing it in files would break old programs. Also there are efficiency reasons for keeping it on, which you can probably find in previous answers on the subject. Maybe this will change - recently they've decided to bite the bullet and fix a lot of old cruft in the Haskell libraries, even if they break some old programs. – Ørjan Johansen Sep 18 '15 at 13:11
  • @ReidBarton Thanks for the url. It certainly helps a lot understanding better the working configurations of GHCi and GHC. – mljrg Sep 20 '15 at 00:37

1 Answers1

3

Regarding point 3:

You can make code run exactly in the same way in both ghc and ghci: use only pure and safe functions. By doing this you know that optimizations or side-effects will not show any different behaviour due to the implementation (as in the question you linked).

No special flag is required. If you do not follow this advice then there is no flag that allows to obtain what you want.

Regarding point 2:

You can make ghci recompile every file and use the interpreter version instead of loading the binary compiled by ghc so you can be sure the code will act as if typed by ghci instead of compiled by ghc. Use the :reload command to force recompilation.


Regarding the types and defaulting (point 1):

GHCi by default uses the extended defaulting rules, which are described here.

Standard defaulting rules basically default only "numbers" (i.e. Num, Fractional etc.). Extended rules are able to default types for things like Eq, Ord and Show.

Note that the default declaration implicit when using ExtendedDefaultRules is:

default ((), Integer, Double)

So, basically, any "free" Eq or Ord constraint is simply defaulted to ().

So you can simply specify ExtendedDefaultRules or NoExtendedDefaultRules to specify exactly which kind of defaulting you want.

This can be done putting the pragmas in the source files {-# LANGUAGE <extension-name> #-} or by specifying -X<extension-name> when compiling with ghc or by using the GHCi directive :set -X<extension-name>.


As noted by dfeur there is a fundamental difference between ghci and ghc: ghci must be able to completely infer the type of the input text when it is inserted. So, obviously, you have to arrange the declarations so that a function doesn't reference an undefined name.

Moreover type defaulting will be applied to each statement which means that, together with the monomorphism restriction (see: What is the monomorphism restriction? and https://wiki.haskell.org/Monomorphism_restriction) ghci may infer more monomorphic types than the ones inferred by ghc when compiling the same code.

You probably want to use NoMonomorphismRestriction when using GHCi (though recent versions of ghci have it disabled by default) and probably in your files too.

Community
  • 1
  • 1
Bakuriu
  • 98,325
  • 22
  • 197
  • 231
  • Ah yes, I forgot that bigger issue of global scope! – dfeuer Sep 17 '15 at 19:46
  • Regarding your response to question 3): Removing the trace stuff from the file in my other question and the `main`, I get only pure code, still loading the file in GHCi fails, so even with pure code there are differences between code at the prompt and that in a file loaded via `:load` command. – mljrg Sep 18 '15 at 10:40
  • Regarding your response to question 2): I was always loading the file using `:load`, and even then the code in the file only got loaded when I added the `{-# LANGUAGE ExtendedDefaultRules #-}` in the file. Why does not GHCi and GHC start with the same default configuration? – mljrg Sep 18 '15 at 10:43
  • Regarding your response to question 1): In fact, by putting `{-# LANGUAGE NoMonomorphismRestriction #-}` in the file this loaded successfully into GHCi (the same if I put only `{-# LANGUAGE ExtendedDefaultRules #-}`. So my questions are the same again: Why does not GHCi and GHC start with the same default configuration? Why is this monomorphism restriction still around? – mljrg Sep 18 '15 at 10:48