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.
Related
How do I lookup type operator name? This does not work:
IssueTH.hs:
{-# LANGUAGE TemplateHaskell #-}
module IssueTH where
import Language.Haskell.TH
f :: Q [Dec]
f = do
Just n <- lookupTypeName "GHC.TypeLits.*"
return []
Issue.hs:
{-# LANGUAGE TemplateHaskell #-}
module Issue where
import IssueTH
$f
ghc Issue.hs fails with message:
Pattern match failure in do expression at IssueTH.hs
Replacing "GHC.TypeLits.*" with "GHC.TypeLits.(*)" or "*" doesn't work either.
I guess I have enough now for a brief answer. Alas I only found the reason for your problem, but not how to solve it.
My testing shows that lookupTypeName does support type operators, but only if they start with :.
Originally this was a requirement, in analogy with infix data constructors, but this was lifted to allow things like the arithmetical type operators in GHC.TypeLits. (The downside is that you can no longer have type operator variables, as were once popular for things like Arrow code.)
Presumably lookupTypeName was not updated to take this into account, and I have filed a bug report for this.
EDIT: A fix for this has finally been made, and should be in the upcoming GHC 8.2.1.
I have a module coded and working, however I can't manage to enter two function signatures for it, because to enter them I must enable the TypeFamilies extension for the module, and when I do that, it no longer builds.
For one of them I need TypeFamilies because it's using persisent/esqueleto functions.
The proper type would be, I believe:
getByIds :: (PersistEntityBackend a ~ SqlBackend) =>
EntityField a (Key a) -> [Key a] -> SqlPersistM [Entity a]
(ghc suggests a more generic signature)
The other one uses hsqml.
ghc suggests this signature but I guess it could be simplified:
prop :: forall tr b.
(Marshal tr, Typeable b, MarshalMode tr ICanReturnTo () ~ Yes) =>
String -> (b -> tr) -> Member (GetObjType (ObjRef b))
The bottom line is, that without TypeFamilies I cannot write those signatures. The moment I enable TypeFamilies, however, the code won't build, and I don't understand why. The error looks like some polymorphic functions suddenly became monomorphic.
The error output is relatively long, you can find it here.
I have TypeFamilies enabled in several other modules of the application without problems, and that enables me to write signatures using both the SqlBackend & ICanReturnTo constraints without problems.
Is there something wrong with that module that prevents it from building with TypeFamilies? Or should I enable yet another extension to fix it? I didn't expect just enabling that extension to break the compilation.
The type equality constraint ~ can only be written out if you have either TypeFamilies or GADTs enabled.
However, enabling TypeFamilies or GADTs also enables MonoLocalBinds. As the name says, it disables generalization of locally defined variables.
If MonoLocalBinds prevents code from compiling, you should either write out the generalized type signatures or factor out such locals into top-level definitions. Sometimes writing out the generalized types is a bit difficult; in such cases you can try querying GHCi, or you can enable NoMonomorphismRestriction, write unannotated top-level definitions and then look at the inferred types.
This expression is incorrect.
f = show
However, in ghci this is legit
let f = show
Moreover, its type is changed to
() -> String
Is there any explanation of this phenomenon?
The ghci prompt behaves as if the ExtendedDefaultRules extension is enabled.
In particular this means that:
The unit type () is added to the start of the standard list of types
which are tried when doing type defaulting.
So to get the same behaviour from a source file, either compile with -XExtendedDefaultRules, or add {-# LANGUAGE ExtendedDefaultRules #-} to the top of the file.
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(..)
-- ...
)
I'm using GHCi 7.0.3 with the following program that implements type-level list:
{-# LANGUAGE TypeOperators #-}
data True
data False
-- List
data Nil
data Cons x xs
-- Type-level infix operator must begin with ':'
data x ::: xs
infixr 5 ::: -- set precedence level to 5 (tight)
It compiles, but when I test it with:
:t (undefined :: True:::Nil)
(what's the type of undefined when cast to type True:::Nil?) I get this error:
Illegal operator `:::' in type `True ::: Nil'
Use -XTypeOperators to allow operators in types
And indeed, when I start GHCi with the flag
-XTypeOperators
I get the expected result:
(undefined :: True ::: Nil) :: True ::: Nil
My question is: Why doesn't the equivalent pragma work:
{-# LANGUAGE TypeOperators #-}
Edit: If pragmas don't extend to GHCi environment than I have another puzzle. I tried this program:
class And b1 b2 b | b1 b2 -> b where
andf :: b1 -> b2 -> b
-- truth table
instance And True True True where andf = undefined
instance And True False False where andf = undefined
instance And False True False where andf = undefined
instance And False False False where andf = undefined
It required the following pragmas:
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
But once compiled, I could use it in GHCi:
*Main> :t andf (undefined::True) (undefined::False)
andf (undefined::True) (undefined::False) :: False
I guess in the list case the interpreter couldn't even parse the expression with type-level operator :::, whereas in the case of multiparameter classes the command line was parseable. But, come to think of it, GHCi performed type inference using multi-parameter classes and functional dependencies, didn't it? This type inference is done in GHCi, and not by calling some function in the compiled code, right?
The other answers are correct about enabling the extension in GHCi, either from the GHCi prompt or as a flag when starting GHCi. There is a third option, however--you can create a .ghci file that will be loaded and run every time you start GHCi, and use that to enable the extension automatically. Particularly for things like TypeOperators, where there's very little harm in having it enabled, it's nicely convenient.
For example, here's what mine looks like right now:
:set prompt "∀x. x ⊢ "
:set -XTypeOperators
import Control.Monad
import Control.Applicative
import Control.Arrow
The .ghci file goes in whatever your system's standard location is for such files.
To answer your extended question: The code in question works in GHCi roughly because it would also work if used in another module, which imported the module using the pragmas but didn't enable them itself. GHC is more than capable of enabling extensions on a per-module basis, even when the exported definitions couldn't possibly make sense without an extension, or have inferred types that require it.
The distinction is a little fuzzy in GHCi because it also puts non-exported definitions from the module in scope, but in general anything that would work if used from another module will also work at the GHCi prompt.
Your pragma is correct; the problem is that you're trying to use it from within GHCi, which doesn't inherit the extensions of the loaded module,1 but does pass the options it's given to GHC to compile the files you list (which is why it has the same effect as the pragma).
You should keep the pragma, and either pass -XTypeOperators when you start GHCi, or enable it after loading the file as follows:
GHCi> :set -XTypeOperators
1 Which could be very undesirable, and probably impossible in many cases, for e.g. loading compiled modules.
The LANGUAGE pragma works for the source file, it is not propagated to the ghci-prompt. Since it is possible to have conflicting pragmas in multiple source files of a project, source pragmas cannot by default propagate to the ghci-prompt. It would be possible to have the pragmas from *modules effective at the prompt, I'm not sure, but I think it is pondered to implement that, anyway, so far, it's not implemented, so you need to set the extensions for ghci explicitly.