iedFlags :: [(ExtensionFlag, TurnOnFlag, ExtensionFlag)]
impliedFlags
  = [ (Opt_RankNTypes,                turnOn, Opt_ExplicitForAll)
    , (Opt_ScopedTypeVariables,       turnOn, Opt_ExplicitForAll)
    , (Opt_LiberalTypeSynonyms,       turnOn, Opt_ExplicitForAll)
    , (Opt_ExistentialQuantification, turnOn, Opt_ExplicitForAll)
    , (Opt_FlexibleInstances,         turnOn, Opt_TypeSynonymInstances)
    , (Opt_FunctionalDependencies,    turnOn, Opt_MultiParamTypeClasses)

    , (Opt_RebindableSyntax, turnOff, Opt_ImplicitPrelude)      -- NB: turn off!

    , (Opt_GADTs,            turnOn, Opt_GADTSyntax)
    , (Opt_GADTs,            turnOn, Opt_MonoLocalBinds)
    , (Opt_TypeFamilies,     turnOn, Opt_MonoLocalBinds)

    , (Opt_TypeFamilies,     turnOn, Opt_KindSignatures)  -- Type families use kind signatures
    , (Opt_PolyKinds,        turnOn, Opt_KindSignatures)  -- Ditto polymorphic kinds

    -- AutoDeriveTypeable is not very useful without DeriveDataTypeable
    , (Opt_AutoDeriveTypeable, turnOn, Opt_DeriveDataTypeable)

    -- We turn this on so that we can export associated type
    -- type synonyms in subordinates (e.g. MyClass(type AssocType))
    , (Opt_TypeFamilies,     turnOn, Opt_ExplicitNamespaces)
    , (Opt_TypeOperators, turnOn, Opt_ExplicitNamespaces)

    , (Opt_ImpredicativeTypes,  turnOn, Opt_RankNTypes)

        -- Record wild-cards implies field disambiguation
        -- Otherwise if you write (C {..}) you may well get
        -- stuff like " 'a' not in scope ", which is a bit silly
        -- if the compiler has just filled in field 'a' of constructor 'C'
    , (Opt_RecordWildCards,     turnOn, Opt_DisambiguateRecordFields)

    , (Opt_ParallelArrays, turnOn, Opt_ParallelListComp)

    -- An implicit parameter constraint, `?x::Int`, is desugared into
    -- `IP "x" Int`, which requires a flexible context/instance.
    , (Opt_ImplicitParams, turnOn, Opt_FlexibleContexts)
    , (Opt_ImplicitParams, turnOn, Opt_FlexibleInstances)

    , (Opt_JavaScriptFFI, turnOn, Opt_InterruptibleFFI)
  ]

op
impliedFlags :: [(ExtensionFlag, TurnOnFlag, ExtensionFlag)]
impliedFlags
  = [ (Opt_RankNTypes,                turnOn, Opt_ExplicitForAll)
    , (Opt_ScopedTypeVariables,       turnOn, Opt_ExplicitForAll)
    , (Opt_LiberalTypeSynonyms,       turnOn, Opt_ExplicitForAll)
    , (Opt_ExistentialQuantification, turnOn, Opt_ExplicitForAll)
    , (Opt_FlexibleInstances,         turnOn, Opt_TypeSynonymInstances)
    , (Opt_FunctionalDependencies,    turnOn, Opt_MultiParamTypeClasses)

    , (Opt_RebindableSyntax, turnOff, Opt_ImplicitPrelude)      -- NB: turn off!

    , (Opt_GADTs,            turnOn, Opt_GADTSyntax)
    , (Opt_GADTs,            turnOn, Opt_MonoLocalBinds)
    , (Opt_TypeFamilies,     turnOn, Opt_MonoLocalBinds)

    , (Opt_TypeFamilies,     turnOn, Opt_KindSignatures)  -- Type families use kind signatures
    , (Opt_PolyKinds,        turnOn, Opt_KindSignatures)  -- Ditto polymorphic kinds

    -- AutoDeriveTypeable is not very useful without DeriveDataTypeable
    , (Opt_AutoDeriveTypeable, turnOn, Opt_DeriveDataTypeable)

    -- We turn this on so that we can export associated type
    -- type synonyms in subordinates (e.g. MyClass(type AssocType))
    , (Opt_TypeFamilies,     turnOn, Opt_ExplicitNamespaces)
    , (Opt_TypeOperators, turnOn, Opt_ExplicitNamespaces)

    , (Opt_ImpredicativeTypes,  turnOn, Opt_RankNTypes)

        -- Record wild-cards implies field disambiguation
        -- Otherwise if you write (C {..}) you may well get
        -- stuff like " 'a' not in scope ", which is a bit silly
        -- if the compiler has just filled in field 'a' of constructor 'C'
    , (Opt_RecordWildCards,     turnOn, Opt_DisambiguateRecordFields)

    , (Opt_ParallelArrays, turnOn, Opt_ParallelListComp)

    -- An implicit parameter constraint, `?x::Int`, is desugared into
    -- `IP "x" Int`, which requires a flexible context/instance.
    , (Opt_ImplicitParams, turnOn, Opt_FlexibleContexts)
    , (Opt_ImplicitParams, turnOn, Opt_FlexibleInstances)

    , (Opt_JavaScriptFFI, turnOn, Opt_InterruptibleFFI)
  ]
impliedFlags
  = [ (Opt_RankNTypes,                turnOn, Opt_ExplicitForAll)
    , (Opt_ScopedTypeVariables,       turnOn, Opt_ExplicitForAll)
    , (Opt_LiberalTypeSynonyms,       turnOn, Opt_ExplicitForAll)
    , (Opt_ExistentialQuantification, turnOn, Opt_ExplicitForAll)
    , (Opt_FlexibleInstances,         turnOn, Opt_TypeSynonymInstances)
    , (Opt_FunctionalDependencies,    turnOn, Opt_MultiParamTypeClasses)

    , (Opt_RebindableSyntax, turnOff, Opt_ImplicitPrelude)      -- NB: turn off!

    , (Opt_GADTs,            turnOn, Opt_GADTSyntax)
    , (Opt_GADTs,            turnOn, Opt_MonoLocalBinds)
    , (Opt_TypeFamilies,     turnOn, Opt_MonoLocalBinds)

    , (Opt_TypeFamilies,     turnOn, Opt_KindSignatures)  -- Type families use kind signatures
    , (Opt_PolyKinds,        turnOn, Opt_KindSignatures)  -- Ditto polymorphic kinds

    -- AutoDeriveTypeable is not very useful without DeriveDataTypeable
    , (Opt_AutoDeriveTypeable, turnOn, Opt_DeriveDataTypeable)

    -- We turn this on so that we can export associated type
    -- type synonyms in subordinates (e.g. MyClass(type AssocType))
    , (Opt_TypeFamilies,     turnOn, Opt_ExplicitNamespaces)
    , (Opt_TypeOperators, turnOn, Opt_ExplicitNamespaces)

    , (Opt_ImpredicativeTypes,  turnOn, Opt_RankNTypes)

        -- Record wild-cards implies field disambiguation
        -- Otherwise if you write (C {..}) you may well get
        -- stuff like " 'a' not in scope ", which is a bit silly
        -- if the compiler has just filled in field 'a' of constructor 'C'
    , (Opt_RecordWildCards,     turnOn, Opt_DisambiguateRecordFields)

    , (Opt_ParallelArrays, turnOn, Opt_ParallelListComp)

    -- An implicit parameter constraint, `?x::Int`, is desugared into
    -- `IP "x" Int`, which requires a flexible context/instance.
    , (Opt_ImplicitParams, turnOn, Opt_FlexibleContexts)
    , (Opt_ImplicitParams, turnOn, Opt_FlexibleInstances)

    , (Opt_JavaScriptFFI, turnOn, Opt_InterruptibleFFI)
  ]