subst ::
    forall t.
    ApplyNominal t =>
    T.Types # QVarInstances Pure ->
    Pure # t ->
    Pure # t
subst params (Pure x) =
    withDict (applyNominalRecursive (Proxy @t)) $
    _Pure #
    case x ^? quantifiedVar of
    Nothing -> hmap (Proxy @ApplyNominal #> subst params) x
    Just q ->
        params ^?
        hNodeLens . _QVarInstances . Lens.ix q . _Pure
        & fromMaybe (quantifiedVar # q)

-- Will loop forever for bottoms like: newtype Void = Void Void
subst ::
    forall t.
    ApplyNominal t =>
    T.Types # QVarInstances Pure ->
    Pure # t ->
    Pure # t
subst params (Pure x) =
    withDict (applyNominalRecursive (Proxy @t)) $
    _Pure #
    case x ^? quantifiedVar of
    Nothing -> hmap (Proxy @ApplyNominal #> subst params) x
    Just q ->
        params ^?
        hNodeLens . _QVarInstances . Lens.ix q . _Pure
        & fromMaybe (quantifiedVar # q)

-- Will loop forever for bottoms like: newtype Void = Void Void
subst params (Pure x) =
    withDict (applyNominalRecursive (Proxy @t)) $
    _Pure #
    case x ^? quantifiedVar of
    Nothing -> hmap (Proxy @ApplyNominal #> subst params) x
    Just q ->
        params ^?
        hNodeLens . _QVarInstances . Lens.ix q . _Pure
        & fromMaybe (quantifiedVar # q)

-- Will loop forever for bottoms like: newtype Void = Void Void