How does Haskell hide data constructor? - haskell

I explored System.Random.StdGen and saw this code in the source.
data StdGen = StdGen Int32 Int32
It seems the module export StdGen too.
module System.Random (
RandomGen(next, split, genRange)
, StdGen
...
However, why can't I do this in my code, say like,
Prelude System.Random> StdGen 1 2
Not in scope: data constructor `System.Random.StdGen'**
In the other hand, I can do this,
module F (Foo) where
import GHC.Int
data Foo = Foo GHC.Int.Int32 GHC.Int.Int32 deriving (Show)
and
Prelude> Foo 1 2
Foo 1 2
Would someone please kindly tell me how actually this data constructor is hidden?

There are two things to understand here. Export syntax and a difference in GHCi behaviour between compiled and interpreted values.
Export syntax
Exporting from a module using this syntax
module System.Random (
-- ...
, StdGen
-- ...
tells GHC only to export the datatype, not the constructor (even if both have the same name). The constructor can be listed explicitly within parentheses after the datatype name if you want to export it, like this:
StdGen(StdGen)
Or you can export a datatype with all its constructors like this:
StdGen(..)
GHCi behaviour
In addition, GHCi, when loading an interpreted module, always allows you to see all the entities visisble at the top-level of the module, even if they're hidden by the export list. This is to facilitate development and debugging, and is the reason why your Foo is visible.
This mode where "everything" is visible is reflected by putting a * in front of the module name at the GHCi prompt. If there's a *, everything is visisble, and if not, then the exported entities are visible.
When using the :m command to add or remove modules from scope, you can select whether you want to add modules in *-form or not.
But for compiled modules (and a library module like System.Random usually is compiled), the *-form is not available, so for these you'll always be in the situation that the export list is respected.
See the documentation for a full description of the scoping behaviour of GHCi.

If you look at the sources, you'll see something along the lines of:
module System.Random
(
-- stuff...
, StdGen
-- even more stuff...
)
This syntax means that only the type is exported, not its constructor(s). If you want to export the constructor too, you'd do:
module System.Random
( StdGen(..)
-- ...
)

Related

Haskell error when using the isNothing function in Maybe

I am trying to use isNothing in my code in Haskell, and it is giving me the error
<interactive>:97:23: error:
• Variable not in scope: isNothing :: Maybe t -> Bool
• Perhaps you meant data constructor ‘Nothing’ (imported from Prelude)
The code line I have is as follows -
maybeMap f value = if isNothing (value) then value else Just (f (check value))
this works fine if I replace isNothing value with value == Nothing, so I am confused why the previous is not working.
First thing's first, the key phrase in the error message is:
Variable not in scope: isNothing
Which means that the compiler just isn't aware of anything named isNothing.
That immediately tells you that the code around your your use of isNothing doesn't matter. It's not a problem with types, or anything to do with the actual isNothing function you're trying to call, and there's no way you can change the code around isNothing to get this to work.
Variable not in scope almost always means one of three things:
You haven't imported the name you're trying to use
You have accidentally misspelled the name you're trying to use
You intended to define something with that name, but haven't done so yet
Changing any of the code surrounding your use of isNothing isn't going to change any of those 3 problems no matter which it is. Even looking at that code isn't going to tell you anything relevant; just closely look at the spelling of the name in the error message to confirm you haven't just made a typo, and if not you know you need to look elsewhere.
In this case it's #1. There are a bunch of useful functions that are in the Haskell Prelude which are automatically imported for you, so you're probably used to just using functions without importing them, but the "normal" case is that to use anything that's already defined you have to import it. isNothing isn't in the Prelude, so that means to use it you have to find out which module it is in and add an import declaration to make it available. (If that module is in a package that isn't already installed, you will also have to obtain the package; that's a question I'm not going to address here)
isNothing comes from the Data.Maybe module (in the base package, which is always installed as part of installing GHC, so no worries there). So you need to use:
import Data.Maybe
If you're working in a file you need to add that to the top of the file (just after the module header, but before you define any names yourself; all imports must come before any of your own code). If you're using the interpreter you can just enter the import as a command.
That will bring all of the names defined in Data.Maybe into scope. If you want more control, you can explicitly import only some of the names, like this:
import Data.Maybe ( isNothing, isJust, listToMaybe )
The function isNothing is not part of the standard prelude. Rather, it's distributed as part of the Data.Maybe module. To use isNothing, you'll need to explicitly import that module:
import Data.Maybe

Why do these corner cases in Haskell's import-as work and what do they do?

I've come across some modules that contain particularly strange imports.
First of all, I have seen a module A that imports an other module as himself. For example:
-- module A.hs
module A where
import B as A -- ???
f = id
What does this do? Why is the above permitted at all?
However what most troubles me is that the code is actually of this kind:
module A where
import B as A -- Okay, assume this works...
import C as A -- ??? A is already defined!
f = id
Why can more then one module be imported with the same name? What does this achieve?
I thought that these kind of imports weren't permitted and also A Gentle Introduction to Haskell states that:
it is illegal to import two different entities having the same name
into the same scope.
However these imports work fine. Yet an other strange thing that bugs me is exporting the module itself:
module A (module A) where
To summarize, given the following MWE:
-- A.hs
module A (module A) where
import B as A
import C as A
f = id
-- B.hs
module B where
g = id
-- C.hs
module C where
h = id
Are the imports following the standards or is this some bug of GHC? It doesn't look like a bug, but I can't find any reference that explains all these corner cases.
What's the exact result achieved? I mean: which names are imported and/or exported from A?
Name qualifiers are not the same thing as module names. A name qualifier is just a collective scope, you can make it refer to any number of modules. Normally you won't add more than one, but in one case you almost always add plenty of modules: in the unqualified scope. import Data.List might be read as something like import qualified Data.List as "": it arranges that, say, sortBy will be found when referring to it with an "empty qualifier", i.e. with none. But we could "rename" that scope:
module Main where
import qualified Prelude as P
import qualified Data.List as P
import qualified Data.Ord as P
main :: P.IO ()
main = do -- `do` is syntax, not a name!
P.print P.. P.map P.snd P.$ P.sortBy (P.comparing P.fst)
[(4,'o'),(6,' '),(0,'H'),(1,'e'),(3,'l'),(9,'r'),(7,'W'),(10,'l'),(8,'o'),(2,'l'),(5,','),(11,'d'),(12,'!')]
The only qualifiers that are fixed are the ones specific to the module in your file itself: that's always both in unqualified scope, and in the scope automatically named after the module. And for definitions, you must use the unqualified form.
For module A (module A), that seems pretty much bogus. I don't think module exports are really well thought-through. They only work properly when you refer to an actual module, not just a name qualifier, i.e.
module PowerPrelude (module A)
import qualified Prelude as A
import qualified Data.List as A
import qualified Data.Ord as A
will not work. Which makes you wonder why it's allowed to declare such an export at all. Might indeed be a bug here.

Haskell: Template Haskell and the scope

This code is compiled fine:
data None = None { _f :: Int }
type Simpl = Env
type Env = Int
However, I got an error with this code:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data None = None { _f :: Int }
type Simpl = Env
makeLenses ''None
type Env = Int
Error:
Not in scope: type constructor or class `Env'
I just added a single line makeLenses ''None between type declarations.
This means TemplateHaskell code could change the scope of type constructor?
Does anyone know the detail about this issue(or how to avoid this problem)?
If you reorder your code as follows, it works:
{-# LANGUAGE TemplateHaskell #-}
import Control.Lens
data None = None { _f :: Int }
type Simpl = Env
type Env = Int
makeLenses ''None
When you use Template Haskell splices to add new top-level declarations to your code, as makeLenses does, the order of declarations in your code suddenly matters!
The reason is that normally compiling a Haskell program involves first collecting all the top-level declarations and reordering them internally to put them in dependency order, and then compiling them one by one (or group by group for mutually recursive declarations).
With new declarations being introduced by running arbitrary code, because GHC doesn't know which declarations makeLenses might need to run, and also it doesn't know which new declarations it will produce. So it can't put the whole file in dependency order and just sort of gives up and expects the user to do it themselves, at least for deciding whether declarations should go before or after the splice.
The only online reference I can find that explains this is in the original Template Haskell paper, section 7.2, where it says that the algorithm is:
Group the declarations as follows:
[d1,...,da]
splice ea
[da+2,...,db]
splice eb
...
splice ez
[dz+2,...,dN]
where the only splice declarations are the ones indicated explicitly, so that each group [d1,...,da], etc, are all ordinary Haskell declarations.
Perform conventional dependency analysis, followed by type checking, on the first group. All its free variables should be in scope.
So the problem here is that the first group of declarations before the splice is being handled separately to the second group after the splice, and it can't see the definition of Env.
My general rule of thumb is to put splices like this at the bottom of the file if possible, but I don't think it's guaranteed that this will always work.

How can I view the definition of a function in Haskell/GHCi?

I'm using Haskell 2010.1.0.0.1 with GHC 6. Typing :t at the GHCi prompt followed by the name of a function shows us the type of the function. Is there a way to view the function definition as well?
Not currently.
The closest command to what you want is :info
:info name ...
Displays information about the given name(s). For example, if name is a class, then the class methods and their types will be printed; if name is a type constructor, then its definition will be printed; if name is a function, then its type will be printed. If name has been loaded from a source file, then GHCi will also display the location of its definition in the source.
For types and classes, GHCi also summarises instances that mention them. To avoid showing irrelevant information, an instance is shown only if (a) its head mentions name, and (b) all the other things mentioned in the instance are in scope (either qualified or otherwise) as a result of a :load or :module commands.
like so:
Prelude> :info ($)
($) :: (a -> b) -> a -> b -- Defined in GHC.Base
infixr 0 $
You can though, see the source for identifiers generated by the haddock tool, on Hackage.
Look up the module on Hackage
Click on the source link
Note that "?src" is a valid command in lambdabot, on the #haskell IRC channel, and does what you'd expect.
> ?src ($)
> f $ x = f x
I don't think so. You can use :i for a little bit more information (more useful for infix operators and data constructions, etc.), but not the definition:
ghci> :i repeat
repeat :: a -> [a] -- Defined in GHC.List
You can use hoogle to quickly find the documentation for a standard library function, which on the right has a link to go to the source. It's still a few clicks away though.
Nope, can't do that. Some fun things you, the Haskell beginner, can do:
On the HTML haddock documents, click on "source"... study the source.
:browse to find all of the definitions exported by a module
Use :help for the obvious result
use the web interface of hoogle to search for functions, or install hoogle locally!
?
Profit!

Haskell modules: hidden names and ghci

I'm trying to export just a subset of names from a Haskell module, but ghci happily lets me access even the hidden names.
module Hiding (shown, calc) where
calc = shown * hidden
shown :: Int
shown = 3
hidden :: Int
hidden = 2
But when trying this in ghci I get:
Prelude> :l Hiding.hs
[1 of 1] Compiling Hiding ( Hiding.hs, interpreted )
Ok, modules loaded: Hiding.
*Hiding> hidden
2
What am I doing wrong?
(Edit: for what it's worth, I'm using ghci 6.12.3 on Arch Linux)
It looks like GHCi is loading your module for you to inspect it, i.e. putting you in the scope of the module. Two hints at that are the prompt *Hiding> and the fact that you accessed the hidden function.
Edit:
End there it is: http://www.haskell.org/ghc/docs/latest/html/users_guide/interactive-evaluation.html#id3045728
It looks to me like you've done the right thing. If you attempt to reference that module from another module I'll bet hidden refuses to work. Could be that GHCI is all-knowing :)

Resources