| Opt_ImpredicativeTypes
| Opt_TypeOperators
| Opt_PackageImports
+ | Opt_NewQualifiedOperators
| Opt_PrintExplicitForalls
( "OverlappingInstances", Opt_OverlappingInstances, const Supported ),
( "UndecidableInstances", Opt_UndecidableInstances, const Supported ),
( "IncoherentInstances", Opt_IncoherentInstances, const Supported ),
- ( "PackageImports", Opt_PackageImports, const Supported )
+ ( "PackageImports", Opt_PackageImports, const Supported ),
+ ( "NewQualifiedOperators", Opt_NewQualifiedOperators, const Supported )
]
impliedFlags :: [(DynFlag, DynFlag)]
-- - M... should be 3 tokens, not 1.
-- - pragma-end should be only valid in a pragma
+-- qualified operator NOTES.
+--
+-- - If M.(+) is a single lexeme, then..
+-- - Probably (+) should be a single lexeme too, for consistency.
+-- Otherwise ( + ) would be a prefix operator, but M.( + ) would not be.
+-- - But we have to rule out reserved operators, otherwise (..) becomes
+-- a different lexeme.
+-- - Should we therefore also rule out reserved operators in the qualified
+-- form? This is quite difficult to achieve. We don't do it for
+-- qualified varids.
+
{
{-# OPTIONS -w #-}
-- The above warning supression flag is a temporary kludge.
@conid "#"+ / { ifExtension magicHashEnabled } { idtoken conid }
}
--- ToDo: M.(,,,)
-
+-- ToDo: - move `var` and (sym) into lexical syntax?
+-- - remove backquote from $special?
<0> {
- @qual @varsym { idtoken qvarsym }
- @qual @consym { idtoken qconsym }
- @varsym { varsym }
- @consym { consym }
+ @qual @varsym / { ifExtension oldQualOps } { idtoken qvarsym }
+ @qual @consym / { ifExtension oldQualOps } { idtoken qconsym }
+ @qual \( @varsym \) / { ifExtension newQualOps } { idtoken prefixqvarsym }
+ @qual \( @consym \) / { ifExtension newQualOps } { idtoken prefixqconsym }
+ @varsym { varsym }
+ @consym { consym }
}
-- For the normal boxed literals we need to be careful
| ITqconid (FastString,FastString)
| ITqvarsym (FastString,FastString)
| ITqconsym (FastString,FastString)
+ | ITprefixqvarsym (FastString,FastString)
+ | ITprefixqconsym (FastString,FastString)
| ITdupipvarid FastString -- GHC extension: implicit param: ?x
popContext
return (L span ITccurly)
-qvarid buf len = ITqvarid $! splitQualName buf len
-qconid buf len = ITqconid $! splitQualName buf len
+qvarid buf len = ITqvarid $! splitQualName buf len False
+qconid buf len = ITqconid $! splitQualName buf len False
-splitQualName :: StringBuffer -> Int -> (FastString,FastString)
+splitQualName :: StringBuffer -> Int -> Bool -> (FastString,FastString)
-- takes a StringBuffer and a length, and returns the module name
-- and identifier parts of a qualified name. Splits at the *last* dot,
-- because of hierarchical module names.
-splitQualName orig_buf len = split orig_buf orig_buf
+splitQualName orig_buf len parens = split orig_buf orig_buf
where
split buf dot_buf
| orig_buf `byteDiff` buf >= len = done dot_buf
done dot_buf =
(lexemeToFastString orig_buf (qual_size - 1),
- lexemeToFastString dot_buf (len - qual_size))
+ if parens -- Prelude.(+)
+ then lexemeToFastString (stepOn dot_buf) (len - qual_size - 2)
+ else lexemeToFastString dot_buf (len - qual_size))
where
qual_size = orig_buf `byteDiff` dot_buf
conid buf len = ITconid fs
where fs = lexemeToFastString buf len
-qvarsym buf len = ITqvarsym $! splitQualName buf len
-qconsym buf len = ITqconsym $! splitQualName buf len
+qvarsym buf len = ITqvarsym $! splitQualName buf len False
+qconsym buf len = ITqconsym $! splitQualName buf len False
+prefixqvarsym buf len = ITprefixqvarsym $! splitQualName buf len True
+prefixqconsym buf len = ITprefixqconsym $! splitQualName buf len True
varsym = sym ITvarsym
consym = sym ITconsym
qqBit = 18 -- enable quasiquoting
inRulePragBit = 19
rawTokenStreamBit = 20 -- producing a token stream with all comments included
+newQualOpsBit = 21 -- Haskell' qualified operator syntax, e.g. Prelude.(+)
genericsEnabled, ffiEnabled, parrEnabled :: Int -> Bool
always _ = True
qqEnabled flags = testBit flags qqBit
inRulePrag flags = testBit flags inRulePragBit
rawTokenStreamEnabled flags = testBit flags rawTokenStreamBit
+newQualOps flags = testBit flags newQualOpsBit
+oldQualOps flags = not (newQualOps flags)
-- PState for parsing options pragmas
--
.|. standaloneDerivingBit `setBitIf` dopt Opt_StandaloneDeriving flags
.|. transformComprehensionsBit `setBitIf` dopt Opt_TransformListComp flags
.|. rawTokenStreamBit `setBitIf` dopt Opt_KeepRawTokenStream flags
+ .|. newQualOpsBit `setBitIf` dopt Opt_NewQualifiedOperators flags
--
setBitIf :: Int -> Bool -> Int
b `setBitIf` cond | cond = bit b
QCONID { L _ (ITqconid _) }
QVARSYM { L _ (ITqvarsym _) }
QCONSYM { L _ (ITqconsym _) }
+ PREFIXQVARSYM { L _ (ITprefixqvarsym _) }
+ PREFIXQCONSYM { L _ (ITprefixqconsym _) }
IPDUPVARID { L _ (ITdupipvarid _) } -- GHC extension
qtycon :: { Located RdrName } -- Qualified or unqualified
: QCONID { L1 $! mkQual tcClsName (getQCONID $1) }
+ | PREFIXQCONSYM { L1 $! mkQual tcClsName (getPREFIXQCONSYM $1) }
| tycon { $1 }
tycon :: { Located RdrName } -- Unqualified
qvarid :: { Located RdrName }
: varid { $1 }
- | QVARID { L1 $ mkQual varName (getQVARID $1) }
+ | QVARID { L1 $! mkQual varName (getQVARID $1) }
+ | PREFIXQVARSYM { L1 $! mkQual varName (getPREFIXQVARSYM $1) }
varid :: { Located RdrName }
- : varid_no_unsafe { $1 }
+ : VARID { L1 $! mkUnqual varName (getVARID $1) }
+ | special_id { L1 $! mkUnqual varName (unLoc $1) }
| 'unsafe' { L1 $! mkUnqual varName (fsLit "unsafe") }
| 'safe' { L1 $! mkUnqual varName (fsLit "safe") }
| 'threadsafe' { L1 $! mkUnqual varName (fsLit "threadsafe") }
-
-varid_no_unsafe :: { Located RdrName }
- : VARID { L1 $! mkUnqual varName (getVARID $1) }
- | special_id { L1 $! mkUnqual varName (unLoc $1) }
| 'forall' { L1 $! mkUnqual varName (fsLit "forall") }
| 'family' { L1 $! mkUnqual varName (fsLit "family") }
qconid :: { Located RdrName } -- Qualified or unqualified
: conid { $1 }
- | QCONID { L1 $ mkQual dataName (getQCONID $1) }
+ | QCONID { L1 $! mkQual dataName (getQCONID $1) }
+ | PREFIXQCONSYM { L1 $! mkQual dataName (getPREFIXQCONSYM $1) }
conid :: { Located RdrName }
: CONID { L1 $ mkUnqual dataName (getCONID $1) }
getQCONID (L _ (ITqconid x)) = x
getQVARSYM (L _ (ITqvarsym x)) = x
getQCONSYM (L _ (ITqconsym x)) = x
+getPREFIXQVARSYM (L _ (ITprefixqvarsym x)) = x
+getPREFIXQCONSYM (L _ (ITprefixqconsym x)) = x
getIPDUPVARID (L _ (ITdupipvarid x)) = x
getCHAR (L _ (ITchar x)) = x
getSTRING (L _ (ITstring x)) = x
<para> Language options recognised by Cabal can also be enabled using the <literal>LANGUAGE</literal> pragma,
thus <literal>{-# LANGUAGE TemplateHaskell #-}</literal> (see <xref linkend="language-pragma"/>>). </para>
- <para>The flag <option>-fglasgow-exts</option>:
+ <para>The flag <option>-fglasgow-exts</option>
<indexterm><primary><option>-fglasgow-exts</option></primary></indexterm>
- simultaneously enables the following extensions:
- <option>-XForeignFunctionInterface</option>,
- <option>-XImplicitParams</option>,
- <option>-XScopedTypeVariables</option>,
- <option>-XGADTs</option>,
- <option>-XTypeFamilies</option>.
+ is equivalent to enabling the following extensions:
+ <option>-XPrintExplicitForalls</option>,
+ <option>-XForeignFunctionInterface</option>,
+ <option>-XUnliftedFFITypes</option>,
+ <option>-XGADTs</option>,
+ <option>-XImplicitParams</option>,
+ <option>-XScopedTypeVariables</option>,
+ <option>-XUnboxedTuples</option>,
+ <option>-XTypeSynonymInstances</option>,
+ <option>-XStandaloneDeriving</option>,
+ <option>-XDeriveDataTypeable</option>,
+ <option>-XFlexibleContexts</option>,
+ <option>-XFlexibleInstances</option>,
+ <option>-XConstrainedClassMethods</option>,
+ <option>-XMultiParamTypeClasses</option>,
+ <option>-XFunctionalDependencies</option>,
+ <option>-XMagicHash</option>,
+ <option>-XPolymorphicComponents</option>,
+ <option>-XExistentialQuantification</option>,
+ <option>-XUnicodeSyntax</option>,
+ <option>-XPostfixOperators</option>,
+ <option>-XPatternGuards</option>,
+ <option>-XLiberalTypeSynonyms</option>,
+ <option>-XRankNTypes</option>,
+ <option>-XImpredicativeTypes</option>,
+ <option>-XTypeOperators</option>,
+ <option>-XRecursiveDo</option>,
+ <option>-XParallelListComp</option>,
+ <option>-XEmptyDataDecls</option>,
+ <option>-XKindSignatures</option>,
+ <option>-XGeneralizedNewtypeDeriving</option>,
+ <option>-XTypeFamilies</option>.
Enabling these options is the <emphasis>only</emphasis>
- effect of <options>-fglasgow-exts</options>
+ effect of <options>-fglasgow-exts</options>.
We are trying to move away from this portmanteau flag,
and towards enabling features individually.</para>
</para>
</sect2>
+ <sect2>
+ <title>New qualified operator syntax</title>
+
+ <para>A new syntax for referencing qualified operators is
+ planned to be introduced by Haskell', and is enabled in GHC
+ with
+ the <option>-XNewQualifiedOperators</option><indexterm><primary><option>-XNewQualifiedOperators</option></primary></indexterm>
+ option. In the new syntax, the prefix form of a qualified
+ operator is
+ written <literal><replaceable>module</replaceable>.(<replaceable>symbol</replaceable>)</literal>
+ (in Haskell 98 this would
+ be <literal>(<replaceable>module</replaceable>.<replaceable>symbol</replaceable>)</literal>),
+ and the infix form is
+ written <literal>`<replaceable>module</replaceable>.(<replaceable>symbol</replaceable>)`</literal>
+ (in Haskell 98 this would
+ be <literal>`<replaceable>module</replaceable>.<replaceable>symbol</replaceable>`</literal>.
+ For example:
+<programlisting>
+ add x y = Prelude.(+) x y
+ subtract y = (`Prelude.(-)` y)
+</programlisting>
+ The new form of qualified operators is intended to regularise
+ the syntax by eliminating odd cases
+ like <literal>Prelude..</literal>. For example,
+ when <literal>NewQualifiedOperators</literal> is on, it is possible to
+ write the enerated sequence <literal>[Monday..]</literal>
+ without spaces, whereas in Haskell 98 this would be a
+ reference to the operator ‘<literal>.</literal>‘
+ from module <literal>Monday</literal>.</para>
+
+ <para>When <option>-XNewQualifiedOperators</option> is on, the old Haskell
+ 98 syntax for qualified operators is not accepted, so this
+ option may cause existing Haskell 98 code to break.</para>
+
+ </sect2>
+
+
<!-- ====================== HIERARCHICAL MODULES ======================= -->