{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveAnyClass #-}
module Extensions.Types
( Extensions (..)
, ParsedExtensions (..)
, CabalAndModuleExtensions (..)
, ExtensionsResult
, ExtensionsError (..)
, CabalException (..)
, ModuleParseError (..)
, emptyExtensions
, emptyParsedExtensions
, OnOffExtension (..)
, showOnOffExtension
, readOnOffExtension
, readExtension
, mergeExtensions
, mergeAnyExtensions
, default2010Extensions
, SafeHaskellExtension (..)
) where
import Control.Applicative ((<|>))
import Control.Exception (Exception)
import Data.Foldable (foldl')
import Data.List.NonEmpty (NonEmpty (..))
import Data.Set (Set)
import Data.Text (Text)
import GHC.LanguageExtensions.Type (Extension (..))
import Text.Read (readMaybe)
import qualified Data.Set as Set
import qualified Data.Text as Text
import qualified Text.Parsec as Parsec
data Extensions = Extensions
{ Extensions -> Set OnOffExtension
extensionsAll :: !(Set OnOffExtension)
, Extensions -> Maybe SafeHaskellExtension
extensionsSafe :: !(Maybe SafeHaskellExtension)
} deriving stock (Int -> Extensions -> ShowS
[Extensions] -> ShowS
Extensions -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Extensions] -> ShowS
$cshowList :: [Extensions] -> ShowS
show :: Extensions -> String
$cshow :: Extensions -> String
showsPrec :: Int -> Extensions -> ShowS
$cshowsPrec :: Int -> Extensions -> ShowS
Show, Extensions -> Extensions -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Extensions -> Extensions -> Bool
$c/= :: Extensions -> Extensions -> Bool
== :: Extensions -> Extensions -> Bool
$c== :: Extensions -> Extensions -> Bool
Eq)
data ParsedExtensions = ParsedExtensions
{ ParsedExtensions -> [OnOffExtension]
parsedExtensionsAll :: ![OnOffExtension]
, ParsedExtensions -> Maybe SafeHaskellExtension
parsedExtensionsSafe :: !(Maybe SafeHaskellExtension)
} deriving stock (Int -> ParsedExtensions -> ShowS
[ParsedExtensions] -> ShowS
ParsedExtensions -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ParsedExtensions] -> ShowS
$cshowList :: [ParsedExtensions] -> ShowS
show :: ParsedExtensions -> String
$cshow :: ParsedExtensions -> String
showsPrec :: Int -> ParsedExtensions -> ShowS
$cshowsPrec :: Int -> ParsedExtensions -> ShowS
Show, ParsedExtensions -> ParsedExtensions -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ParsedExtensions -> ParsedExtensions -> Bool
$c/= :: ParsedExtensions -> ParsedExtensions -> Bool
== :: ParsedExtensions -> ParsedExtensions -> Bool
$c== :: ParsedExtensions -> ParsedExtensions -> Bool
Eq)
data CabalAndModuleExtensions = CabalAndModuleExtensions
{ CabalAndModuleExtensions -> ParsedExtensions
cabalExtensions :: !ParsedExtensions
, CabalAndModuleExtensions -> ParsedExtensions
moduleExtensions :: !ParsedExtensions
} deriving stock (Int -> CabalAndModuleExtensions -> ShowS
[CabalAndModuleExtensions] -> ShowS
CabalAndModuleExtensions -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CabalAndModuleExtensions] -> ShowS
$cshowList :: [CabalAndModuleExtensions] -> ShowS
show :: CabalAndModuleExtensions -> String
$cshow :: CabalAndModuleExtensions -> String
showsPrec :: Int -> CabalAndModuleExtensions -> ShowS
$cshowsPrec :: Int -> CabalAndModuleExtensions -> ShowS
Show, CabalAndModuleExtensions -> CabalAndModuleExtensions -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CabalAndModuleExtensions -> CabalAndModuleExtensions -> Bool
$c/= :: CabalAndModuleExtensions -> CabalAndModuleExtensions -> Bool
== :: CabalAndModuleExtensions -> CabalAndModuleExtensions -> Bool
$c== :: CabalAndModuleExtensions -> CabalAndModuleExtensions -> Bool
Eq)
type ExtensionsResult = Either ExtensionsError Extensions
data ExtensionsError
= ModuleParseError FilePath ModuleParseError
| CabalError CabalException
| SourceNotFound FilePath
| NotCabalModule FilePath
| SafeHaskellConflict (NonEmpty SafeHaskellExtension)
deriving stock (Int -> ExtensionsError -> ShowS
[ExtensionsError] -> ShowS
ExtensionsError -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ExtensionsError] -> ShowS
$cshowList :: [ExtensionsError] -> ShowS
show :: ExtensionsError -> String
$cshow :: ExtensionsError -> String
showsPrec :: Int -> ExtensionsError -> ShowS
$cshowsPrec :: Int -> ExtensionsError -> ShowS
Show, ExtensionsError -> ExtensionsError -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ExtensionsError -> ExtensionsError -> Bool
$c/= :: ExtensionsError -> ExtensionsError -> Bool
== :: ExtensionsError -> ExtensionsError -> Bool
$c== :: ExtensionsError -> ExtensionsError -> Bool
Eq)
data CabalException
= CabalFileNotFound FilePath
| CabalParseError Text
| CabalSafeExtensionsConflict (NonEmpty SafeHaskellExtension)
deriving stock (Int -> CabalException -> ShowS
[CabalException] -> ShowS
CabalException -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CabalException] -> ShowS
$cshowList :: [CabalException] -> ShowS
show :: CabalException -> String
$cshow :: CabalException -> String
showsPrec :: Int -> CabalException -> ShowS
$cshowsPrec :: Int -> CabalException -> ShowS
Show, CabalException -> CabalException -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CabalException -> CabalException -> Bool
$c/= :: CabalException -> CabalException -> Bool
== :: CabalException -> CabalException -> Bool
$c== :: CabalException -> CabalException -> Bool
Eq)
deriving anyclass (Show CabalException
Typeable CabalException
SomeException -> Maybe CabalException
CabalException -> String
CabalException -> SomeException
forall e.
Typeable e
-> Show e
-> (e -> SomeException)
-> (SomeException -> Maybe e)
-> (e -> String)
-> Exception e
displayException :: CabalException -> String
$cdisplayException :: CabalException -> String
fromException :: SomeException -> Maybe CabalException
$cfromException :: SomeException -> Maybe CabalException
toException :: CabalException -> SomeException
$ctoException :: CabalException -> SomeException
Exception)
data ModuleParseError
= ParsecError Parsec.ParseError
| UnknownExtensions (NonEmpty String)
| ModuleSafeHaskellConflict (NonEmpty SafeHaskellExtension)
| FileNotFound FilePath
deriving stock (Int -> ModuleParseError -> ShowS
[ModuleParseError] -> ShowS
ModuleParseError -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ModuleParseError] -> ShowS
$cshowList :: [ModuleParseError] -> ShowS
show :: ModuleParseError -> String
$cshow :: ModuleParseError -> String
showsPrec :: Int -> ModuleParseError -> ShowS
$cshowsPrec :: Int -> ModuleParseError -> ShowS
Show, ModuleParseError -> ModuleParseError -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ModuleParseError -> ModuleParseError -> Bool
$c/= :: ModuleParseError -> ModuleParseError -> Bool
== :: ModuleParseError -> ModuleParseError -> Bool
$c== :: ModuleParseError -> ModuleParseError -> Bool
Eq)
emptyExtensions :: Extensions
emptyExtensions :: Extensions
emptyExtensions = Extensions
{ extensionsAll :: Set OnOffExtension
extensionsAll = forall a. Monoid a => a
mempty
, extensionsSafe :: Maybe SafeHaskellExtension
extensionsSafe = forall a. Maybe a
Nothing
}
emptyParsedExtensions :: ParsedExtensions
emptyParsedExtensions :: ParsedExtensions
emptyParsedExtensions = ParsedExtensions
{ parsedExtensionsAll :: [OnOffExtension]
parsedExtensionsAll = []
, parsedExtensionsSafe :: Maybe SafeHaskellExtension
parsedExtensionsSafe = forall a. Maybe a
Nothing
}
data SafeHaskellExtension
= Unsafe
| Trustworthy
| Safe
deriving stock (Int -> SafeHaskellExtension -> ShowS
[SafeHaskellExtension] -> ShowS
SafeHaskellExtension -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SafeHaskellExtension] -> ShowS
$cshowList :: [SafeHaskellExtension] -> ShowS
show :: SafeHaskellExtension -> String
$cshow :: SafeHaskellExtension -> String
showsPrec :: Int -> SafeHaskellExtension -> ShowS
$cshowsPrec :: Int -> SafeHaskellExtension -> ShowS
Show, ReadPrec [SafeHaskellExtension]
ReadPrec SafeHaskellExtension
Int -> ReadS SafeHaskellExtension
ReadS [SafeHaskellExtension]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [SafeHaskellExtension]
$creadListPrec :: ReadPrec [SafeHaskellExtension]
readPrec :: ReadPrec SafeHaskellExtension
$creadPrec :: ReadPrec SafeHaskellExtension
readList :: ReadS [SafeHaskellExtension]
$creadList :: ReadS [SafeHaskellExtension]
readsPrec :: Int -> ReadS SafeHaskellExtension
$creadsPrec :: Int -> ReadS SafeHaskellExtension
Read, SafeHaskellExtension -> SafeHaskellExtension -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SafeHaskellExtension -> SafeHaskellExtension -> Bool
$c/= :: SafeHaskellExtension -> SafeHaskellExtension -> Bool
== :: SafeHaskellExtension -> SafeHaskellExtension -> Bool
$c== :: SafeHaskellExtension -> SafeHaskellExtension -> Bool
Eq, Eq SafeHaskellExtension
SafeHaskellExtension -> SafeHaskellExtension -> Bool
SafeHaskellExtension -> SafeHaskellExtension -> Ordering
SafeHaskellExtension
-> SafeHaskellExtension -> SafeHaskellExtension
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SafeHaskellExtension
-> SafeHaskellExtension -> SafeHaskellExtension
$cmin :: SafeHaskellExtension
-> SafeHaskellExtension -> SafeHaskellExtension
max :: SafeHaskellExtension
-> SafeHaskellExtension -> SafeHaskellExtension
$cmax :: SafeHaskellExtension
-> SafeHaskellExtension -> SafeHaskellExtension
>= :: SafeHaskellExtension -> SafeHaskellExtension -> Bool
$c>= :: SafeHaskellExtension -> SafeHaskellExtension -> Bool
> :: SafeHaskellExtension -> SafeHaskellExtension -> Bool
$c> :: SafeHaskellExtension -> SafeHaskellExtension -> Bool
<= :: SafeHaskellExtension -> SafeHaskellExtension -> Bool
$c<= :: SafeHaskellExtension -> SafeHaskellExtension -> Bool
< :: SafeHaskellExtension -> SafeHaskellExtension -> Bool
$c< :: SafeHaskellExtension -> SafeHaskellExtension -> Bool
compare :: SafeHaskellExtension -> SafeHaskellExtension -> Ordering
$ccompare :: SafeHaskellExtension -> SafeHaskellExtension -> Ordering
Ord, Int -> SafeHaskellExtension
SafeHaskellExtension -> Int
SafeHaskellExtension -> [SafeHaskellExtension]
SafeHaskellExtension -> SafeHaskellExtension
SafeHaskellExtension
-> SafeHaskellExtension -> [SafeHaskellExtension]
SafeHaskellExtension
-> SafeHaskellExtension
-> SafeHaskellExtension
-> [SafeHaskellExtension]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: SafeHaskellExtension
-> SafeHaskellExtension
-> SafeHaskellExtension
-> [SafeHaskellExtension]
$cenumFromThenTo :: SafeHaskellExtension
-> SafeHaskellExtension
-> SafeHaskellExtension
-> [SafeHaskellExtension]
enumFromTo :: SafeHaskellExtension
-> SafeHaskellExtension -> [SafeHaskellExtension]
$cenumFromTo :: SafeHaskellExtension
-> SafeHaskellExtension -> [SafeHaskellExtension]
enumFromThen :: SafeHaskellExtension
-> SafeHaskellExtension -> [SafeHaskellExtension]
$cenumFromThen :: SafeHaskellExtension
-> SafeHaskellExtension -> [SafeHaskellExtension]
enumFrom :: SafeHaskellExtension -> [SafeHaskellExtension]
$cenumFrom :: SafeHaskellExtension -> [SafeHaskellExtension]
fromEnum :: SafeHaskellExtension -> Int
$cfromEnum :: SafeHaskellExtension -> Int
toEnum :: Int -> SafeHaskellExtension
$ctoEnum :: Int -> SafeHaskellExtension
pred :: SafeHaskellExtension -> SafeHaskellExtension
$cpred :: SafeHaskellExtension -> SafeHaskellExtension
succ :: SafeHaskellExtension -> SafeHaskellExtension
$csucc :: SafeHaskellExtension -> SafeHaskellExtension
Enum, SafeHaskellExtension
forall a. a -> a -> Bounded a
maxBound :: SafeHaskellExtension
$cmaxBound :: SafeHaskellExtension
minBound :: SafeHaskellExtension
$cminBound :: SafeHaskellExtension
Bounded)
data OnOffExtension
= On Extension
| Off Extension
deriving stock (Int -> OnOffExtension -> ShowS
[OnOffExtension] -> ShowS
OnOffExtension -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [OnOffExtension] -> ShowS
$cshowList :: [OnOffExtension] -> ShowS
show :: OnOffExtension -> String
$cshow :: OnOffExtension -> String
showsPrec :: Int -> OnOffExtension -> ShowS
$cshowsPrec :: Int -> OnOffExtension -> ShowS
Show, OnOffExtension -> OnOffExtension -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: OnOffExtension -> OnOffExtension -> Bool
$c/= :: OnOffExtension -> OnOffExtension -> Bool
== :: OnOffExtension -> OnOffExtension -> Bool
$c== :: OnOffExtension -> OnOffExtension -> Bool
Eq, Eq OnOffExtension
OnOffExtension -> OnOffExtension -> Bool
OnOffExtension -> OnOffExtension -> Ordering
OnOffExtension -> OnOffExtension -> OnOffExtension
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: OnOffExtension -> OnOffExtension -> OnOffExtension
$cmin :: OnOffExtension -> OnOffExtension -> OnOffExtension
max :: OnOffExtension -> OnOffExtension -> OnOffExtension
$cmax :: OnOffExtension -> OnOffExtension -> OnOffExtension
>= :: OnOffExtension -> OnOffExtension -> Bool
$c>= :: OnOffExtension -> OnOffExtension -> Bool
> :: OnOffExtension -> OnOffExtension -> Bool
$c> :: OnOffExtension -> OnOffExtension -> Bool
<= :: OnOffExtension -> OnOffExtension -> Bool
$c<= :: OnOffExtension -> OnOffExtension -> Bool
< :: OnOffExtension -> OnOffExtension -> Bool
$c< :: OnOffExtension -> OnOffExtension -> Bool
compare :: OnOffExtension -> OnOffExtension -> Ordering
$ccompare :: OnOffExtension -> OnOffExtension -> Ordering
Ord)
showOnOffExtension :: OnOffExtension -> Text
showOnOffExtension :: OnOffExtension -> Text
showOnOffExtension = \case
On Extension
ext -> Extension -> Text
showExtension Extension
ext
Off Extension
ext -> Text
"No" forall a. Semigroup a => a -> a -> a
<> Extension -> Text
showExtension Extension
ext
where
showExtension :: Extension -> Text
showExtension :: Extension -> Text
showExtension = \case
Extension
Cpp -> Text
"CPP"
#if !MIN_VERSION_ghc_boot_th(9,4,1)
Extension
RecordPuns -> Text
"NamedFieldPuns"
#endif
Extension
ext -> String -> Text
Text.pack forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show Extension
ext
readOnOffExtension :: String -> Maybe OnOffExtension
readOnOffExtension :: String -> Maybe OnOffExtension
readOnOffExtension String
s =
(Extension -> OnOffExtension
On forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> Maybe Extension
readExtension String
s) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Extension -> OnOffExtension
Off forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Extension
readOffExtension)
where
readOffExtension :: Maybe Extension
readOffExtension :: Maybe Extension
readOffExtension = do
(String
"No", String
ext) <- forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Int -> [a] -> ([a], [a])
splitAt Int
2 String
s
String -> Maybe Extension
readExtension String
ext
readExtension :: String -> Maybe Extension
readExtension :: String -> Maybe Extension
readExtension = \case
String
"GeneralisedNewtypeDeriving" -> forall a. a -> Maybe a
Just Extension
GeneralizedNewtypeDeriving
#if !MIN_VERSION_ghc_boot_th(9,4,1)
String
"NamedFieldPuns" -> forall a. a -> Maybe a
Just Extension
RecordPuns
String
"RecordPuns" -> forall a. Maybe a
Nothing
#endif
String
"Rank2Types" -> forall a. a -> Maybe a
Just Extension
RankNTypes
String
"CPP" -> forall a. a -> Maybe a
Just Extension
Cpp
String
"Cpp" -> forall a. Maybe a
Nothing
String
s -> forall a. Read a => String -> Maybe a
readMaybe String
s
mergeExtensions :: [OnOffExtension] -> Set OnOffExtension
mergeExtensions :: [OnOffExtension] -> Set OnOffExtension
mergeExtensions = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Set OnOffExtension -> OnOffExtension -> Set OnOffExtension
handleExt forall a. Set a
Set.empty
where
handleExt :: Set OnOffExtension -> OnOffExtension -> Set OnOffExtension
handleExt :: Set OnOffExtension -> OnOffExtension -> Set OnOffExtension
handleExt Set OnOffExtension
exts (On Extension
e)
| Extension
e forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extension]
default2010Extensions = forall a. Ord a => a -> Set a -> Set a
Set.delete (Extension -> OnOffExtension
Off Extension
e) Set OnOffExtension
exts
| Bool
otherwise = forall a. Ord a => a -> Set a -> Set a
Set.insert (Extension -> OnOffExtension
On Extension
e) Set OnOffExtension
exts
handleExt Set OnOffExtension
exts (Off Extension
e)
| Extension
e forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extension]
default2010Extensions = forall a. Ord a => a -> Set a -> Set a
Set.insert (Extension -> OnOffExtension
Off Extension
e) Set OnOffExtension
exts
| Bool
otherwise = forall a. Ord a => a -> Set a -> Set a
Set.delete (Extension -> OnOffExtension
On Extension
e) Set OnOffExtension
exts
mergeAnyExtensions
:: ParsedExtensions
-> ParsedExtensions
-> ExtensionsResult
mergeAnyExtensions :: ParsedExtensions -> ParsedExtensions -> ExtensionsResult
mergeAnyExtensions (ParsedExtensions [OnOffExtension]
exts1 Maybe SafeHaskellExtension
safe1) (ParsedExtensions [OnOffExtension]
exts2 Maybe SafeHaskellExtension
safe2) = case (Maybe SafeHaskellExtension
safe1, Maybe SafeHaskellExtension
safe2) of
(Maybe SafeHaskellExtension
Nothing, Maybe SafeHaskellExtension
safe) -> forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ Extensions
{ extensionsAll :: Set OnOffExtension
extensionsAll = Set OnOffExtension
mergedExts
, extensionsSafe :: Maybe SafeHaskellExtension
extensionsSafe = Maybe SafeHaskellExtension
safe
}
(Maybe SafeHaskellExtension
safe, Maybe SafeHaskellExtension
Nothing) -> forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ Extensions
{ extensionsAll :: Set OnOffExtension
extensionsAll = Set OnOffExtension
mergedExts
, extensionsSafe :: Maybe SafeHaskellExtension
extensionsSafe = Maybe SafeHaskellExtension
safe
}
(Just SafeHaskellExtension
s1, Just SafeHaskellExtension
s2) ->
if Maybe SafeHaskellExtension
safe1 forall a. Eq a => a -> a -> Bool
== Maybe SafeHaskellExtension
safe2
then forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ Extensions
{ extensionsAll :: Set OnOffExtension
extensionsAll = Set OnOffExtension
mergedExts
, extensionsSafe :: Maybe SafeHaskellExtension
extensionsSafe = Maybe SafeHaskellExtension
safe1
}
else forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ NonEmpty SafeHaskellExtension -> ExtensionsError
SafeHaskellConflict forall a b. (a -> b) -> a -> b
$ SafeHaskellExtension
s1 forall a. a -> [a] -> NonEmpty a
:| [SafeHaskellExtension
s2]
where
mergedExts :: Set OnOffExtension
mergedExts :: Set OnOffExtension
mergedExts = [OnOffExtension] -> Set OnOffExtension
mergeExtensions ([OnOffExtension]
exts1 forall a. Semigroup a => a -> a -> a
<> [OnOffExtension]
exts2)
default2010Extensions :: [Extension]
default2010Extensions :: [Extension]
default2010Extensions =
[ Extension
ImplicitPrelude
, Extension
StarIsType
, Extension
MonomorphismRestriction
, Extension
DatatypeContexts
, Extension
TraditionalRecordSyntax
, Extension
EmptyDataDecls
, Extension
ForeignFunctionInterface
, Extension
PatternGuards
, Extension
DoAndIfThenElse
, Extension
RelaxedPolyRec
#if __GLASGOW_HASKELL__ >= 810
, Extension
CUSKs
#endif
]
deriving stock instance Read Extension
#if __GLASGOW_HASKELL__ < 900
deriving stock instance Ord Extension
#endif